Block Duplication Elimination Pattern

I have a class:

public class VisitorProcessing {
    public void visit(EventA eventA){
           if(condition1....)
                // Do somethings 1
           else{
               if(condition2){
               // Do something 2
               }
               else{
               // Do something 3
               }
           } 
    }
    public void visit(EventB eventB){
           if(condition1....)
                // Do somethings 4
           else{
               if(condition2){
               // Do something 5
               }
               else{
               // Do something 6
               }
           } 
    }
    public void visit(EventC eventC){
           if(condition1....)
                // Do somethings 7
           else{
               if(condition2){
               // Do something 8
               }
               else{
               // Do something 9
               }
           } 
    }
    public void visit(EventD eventD){
           if(condition1....)
                // Do somethings 10
           else{
               if(condition2){
               // Do something 11
               }
               else{
               // Do something 12
               }
           } 
    } 
}

Entire event object Extends the same parent BasicEvent object. And conditions refer only to the event object and can be calculated from the parent event.

I want to start refactoring to group the branching logic in one place, because I'm not sure about the conditions. The only thing I'm sure is the handling of "DoSomthings ...".

So, I am looking for if there is any known template for this.

Thanks in advance

+4
source share
3 answers

The sending method is responsible for the correct call of methods, you just need to write 3 elements each time.

public interface DoSomething {
    void doSomething1();
    void doSomething2();
    void doSomething3();
}

public class VisitorProcessing {

    public void dispatch( DoSomething ds) {
        if(condition1....)
            ds.doSomething1();
       else{
           if(condition2){
               ds.doSomething2();
           }
           else{
               ds.doSomething3();
           }
       } 
    }

    public void visit(EventA eventA){
        DoSomething ds = new DoSomething()
        {
            void doSomething1() {
             // Do somethings 1
            }
            void doSomething2(){
             // Do something 2
            }
            void doSomething3(){
             // Do something 3
            }
        }
        dispatch( ds );
    }

    public void visit(EventB eventB){
        DoSomething ds = new DoSomething()
        {
            void doSomething1() {
             // Do somethings 3
            }
            void doSomething2(){
             // Do something 4
            }
            void doSomething3(){
             // Do something 5
            }
        }
        dispatch( ds );
    }
    ...
}
+4
source

, . , Handler, Handler, , . :

public Class Handler() {
  private Handler next;

  public setNext(Handler next) {
    this.next = next;
  }

  public void action(params) {
    if(some_condition) {
      ...
    }
    else {
      if(next != null)
        next.action(params);
    }
  }
}

, . , , visit. , , .

:

public Class Condition1 extends Handler {
  public void action(BasicEvent e) {
    if (condition1) {
      if(e instanceof EventA) // Do something 1
      if(e instanceof EventB) // Do something 4
      if(e instanceof EventC) // Do something 7
      if(e instanceof EventD) // Do something 10
    }
    else {
      if(next != null)
        next.action(BasicEvent e);
    }
  }
}

public Class Condition2 extends Handler {
  public void action(BasicEvent e) {
    if (condition2) {
      if(e instanceof EventA) // Do something 2
      if(e instanceof EventB) // Do something 5
      if(e instanceof EventC) // Do something 8
      if(e instanceof EventD) // Do something 11
    }
    else {
      if(next != null)
        next.action(BasicEvent e);
    }
  }
}

public Class ConditionElse extends Handler {
  public void action(BasicEvent e) {
    if(e instanceof EventA) // Do something 3
    if(e instanceof EventB) // Do something 6
    if(e instanceof EventC) // Do something 9
    if(e instanceof EventD) // Do something 12

    // we reached the end of the chain
  }
}

, ( ), :

Condition1 condition_1 = new Condition1();
Condition2 condition_2 = new Condition2();
ConditionElse condition_else = new new ConditionElse();

condition_1.setNext(condition_2);
condition_2.setNext(condition_else);

visit:

public void visit(BasicEvent e){
  condition1.action(e);
}

, , . instanceof , 4 , , , .

+1

If you cannot change the visit methods, then what you can do is create a method (EventEvent method) that is called from each of the visit methods.

public class VisitorProcessing {
    public void visit(EventA eventA){
           processEvent(eventA);
           //... EventA specific code goes here
    }
    public void visit(EventB eventB){
           processEvent(eventB);
           //... EventB specific code goes here
    }
    public void visit(EventC eventC){
           processEvent(eventC);
           //... EventC specific code goes here
    }
    public void visit(EventD eventD){
           processEvent(eventD);
           //... EventD specific code goes here
    } 

    private void processEvent(BasicEvent event) {
           if(condition1....)
                // Do somethings 10
           else{
               if(condition2){
               // Do something 11
               }
               else{
               // Do something 12
               }
           } 
    }
}
0
source

All Articles