Search code examples
javadesign-patternscommand-pattern

Implement Command Pattern Effectively


Initial code:

public void updateState(final int state)
{
    preSet();
    itsState = state;
    postSet();
}
public void setTitle(final String title)
{
    preSet();
    itsTitle = title;
    postSet();
}

After my Command Pattern Implementation:

public void updateState(final int state)
{
  CallableManager.doInTransaction(new Callable<Void>()
  {
     @Override
     public Void execute()
     {
       itsHiddenNodes = hiddenNodes;
       return null;
     }
  });
}
public void setTitle(final String title)
{
  CallableManager.doInTransaction(new Callable<Void>()
  {
     @Override
     public Void execute()
     {
       itsTitle = title;
       return null;
     }
  });
}

This interface is created for pass method as parameter.

private interface Callable<T>
{
    public T execute();
}

This class is created to manage command pattern.

private class CallableManager
{
    public <T> static void doInTransaction(final Callable<T> callable)
    {
        preSet();
        callable.execute();
        postSet();
    }
}

As you see, implementing command pattern does not look like very effective at least as line of code for this example. For this example, I implement command pattern to escape from repeated code and decrease the line of code. But as a result both of them are not provided for this example. Please give me some advice. How can I use command pattern effectively?


Solution

  • A lambda can reduce the code duplication considerably. Also, Runnable seems like a more appropriate interface than Callable, since you are not returning a value.

    public class MainJava {
        private int state;
        private String title;
    
        public static void main(String... args) {
            MainJava mj = new MainJava();
            mj.setState(42);
            mj.setTitle("My Title");
        }
    
        public void setState(int state) {
            doInTransaction(() -> this.state = state);
        }
        public void setTitle(String title) {
            doInTransaction(() -> this.title = title);
        }
    
        private void doInTransaction(Runnable runnable) {
            preSet();
            runnable.run();
            postSet();
        }
    
        private void preSet() {
            System.out.println("preset");
        }
        private void postSet() {
            System.out.println("post-set");
        }
    }