How to cut down boilerplate code in composite/decorate pattern

ying :

In composite/decorate patter, the outer container overrides some methods to change the behavior, but have to delegate to sub-component for the rest of methods.

ex: class A has 10 methods, class B contains A but only override 2 methods, then B has to override 8 methods just to delegate to the instance of A inside. How to cut those boilerplate codes in Java and Python?

EDIT: I try not to make B extends A cause I try to be more composite than inheritance.

Supun Wijerathne :

I hope you are simply asking for something like this. I'll take the decorator pattern for example (But you can apply the same to the other also).

class A implements Decorator{    
    @Override
    public void decorate(){
      System.out.print("Decorate A");
    }

    @Override
    public void help(){
      System.out.print("Help");
    }

}

class B implements Decorator{    
    private Decorator member;

    public B(Decorator decorator){
      this.member = decorator;
    }

    @Override
    public void decorate(){
      member.decorate();
      System.out.print("Decorate B");
    }

    @Override 
    public void help(){
      //***you need the behaviour of A here
      member.help();
    }
}

Decorator d = new B(new A());
b.help();

So in line //**, if you want the behavior of A there, just do B extends A instead of extending/implementing the abstract class/interface. Then you do not need to delegate. That behavior will be inherited.

But any way you want to execute the member method there, keeping it more generic and gives the ability to the runtime to decide it, then you have to delegate. There is no any other solution because that logic is encapsulated only inside the member class and you do not know the exact type until the runtime injects the actual member.

You can refer this example, to see how this decorator pattern delegation can be achieved with lombok.

public class RemovalCountingList<E> implements List<E> {
    @Delegate(excludes = ExcludedListMethods.class)
    private final List<E> delegate;
    private final AtomicInteger removalCount = new AtomicInteger();
    public RemovalCountingList(List<E> delegate) {
        this.delegate = delegate;
    }
    @Override
    public E remove(int index) {
        System.out.println("Removal count: " + removalCount.incrementAndGet());
        return delegate.remove(index);
    }
    @Override
    public boolean remove(Object o) {
        boolean isRemoved = delegate.remove(o);
        if (isRemoved) {
            System.out.println("Removal count: " + removalCount.incrementAndGet());
        }
        return isRemoved;
    }
    /**
     * Excluded methods that Lombok will not implement, we will implement/override these methods.
     */
        private abstract class ExcludedListMethods {
            public abstract E remove(int index);
            public abstract boolean remove(Object o);
        }
    }

public class ClientMain {
    public static void main(String[] args) {
        RemovalCountingList<String> cities = new RemovalCountingList<>(new ArrayList<>());
        cities.add("London");
        cities.add("Paris");
        cities.add("Istanbul");
        cities.add("Tokyo");
        String removedCity = cities.remove(0);
        System.out.println("Removed city: " + removedCity);
        boolean isRemoved = cities.remove("Istanbul");
        System.out.println("Is removed?: " + isRemoved);
    }
}

It will help you to remove your boilerplate codes.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=166346&siteId=1