Java: Am I missing a restricting pattern? I need to restrict implementation with only selected methods

StackOverflow https://stackoverflow.com/questions/7553216

  •  29-01-2021
  •  | 
  •  

سؤال

Say I have some class that is too fat of methods for one concrete case, but fits to about a half of them, so it is no way but to extend it. Simultaneously, I want to hide the fact that I've extended this fat class from end-users. Then I want to restrict that class with some new interface and let unneeded methods throw an UnsupportedOperationException:

public class TooFatClass {
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { ... };
    public void notUsefulMethodTwo() { ... };
    public void notUsefulMethodThree() { ... };
    ...
}

public interface OnlyUsefulMethods {
    public void usefulMethodOne();
    public void usefulMethodTwo();
    public void usefulMethodThree();
    ...

    public static OnlyUsefulMethods create() {
        return new OnlyUsefulMethodsImpl();
    }
}

// notice it is package-private
class OnlyUsefulMethodsImpl extends TooFatClass implements OnlyUsefulMethods {
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodTwo() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodThree() { throw new UnsupportedOperationException(); };
    ...        
}

So, OnlyUsefulMethodsImpl instance can be cast to TooFatClass if user really wants, but it hides this fact and do not forces user to do so.

However, java do not allows static methods implementations in interfaces (it is dumb to make it OnlyUsefulMethods abstract, I think), so I finish with this smelly piece of code:

public interface OnlyUsefulMethods {
    public void usefulMethodOne();
    public void usefulMethodTwo();
    public void usefulMethodThree();
    ...

    public static final class Factory {
        public static OnlyUsefulMethods create() { return new OnlyUsefulMethodsImpl(); }
        public static OnlyUsefulMethods create(Options options) { 
               return new OnlyUsefulMethodsImpl(options); }
    }    

}

Even if I'll move a Factory outside of interface it looks too complex to use just for one class case, I want a factory method without showing OnlyUsefulMethodsImpl outside.

Am I doing something wrong / too complex and missing some restricting pattern?


May be relates to this questions (anyway, there are some answers that may be fit, I'm not sure):

هل كانت مفيدة؟

المحلول

Sounds like a good time to delegation.

The "leaner" class wraps the "fat" class and only exposes the interface of the "leaner" class. Some ides can help you implement delegation.

نصائح أخرى

class OnlyUsefulMethods extends TooFatClass{
    public void usefulMethodOne() { ... };
    public void usefulMethodTwo() { ... };
    public void usefulMethodThree() { ... };
    ...
    public void notUsefulMethodOne() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodTwo() { throw new UnsupportedOperationException(); };
    public void notUsefulMethodThree() { throw new UnsupportedOperationException(); };
    ...        
}

Sometimes I wonder why patterns can make things so complicated... No need for factories, you can directly instantiate it with new.

You can also use a composition pattern to wrap the TooFatClass instance inside a class that only exposes the needed methods.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top