Design Patterns (21) Visitor Visitor pattern

In Java, all objects are inherited from the Object object, one of the advantages of doing so is to make a collection of object data structures easy to manage, for example, you can use any type of object into the Vector.

But now there is a problem, if your collection (connection) objects not only store one type of object, if you want to make some individualized operations on these objects, the first condition is to know the object type, use instanceof seems like a good way, in a program the simplest case, perhaps you would be so as:
 public class ElementA { 
    // some implementing 
 } 
 
 public class ElementB { 
    // some implementing 
 } 

 public class ElementC { 
    // some implementing 
 } 

 // ...... 

    Iterator iterator = arrayList.iterator() 
    while (iterator.hasNext()) { 
        if (o instanceof ElementA) 
        (ElementA) o.operationA(); 
        else if (o instanceof ElementB) 
         (ElementB) o.operationB(); 
      else if (o instanceof ElementC) 
         (ElementC) o.operationC(); 
      else 
         System.out.println(
                  "Sorry! I don't know who you are! " 
                   + o.toString()); 
        //....
    }

    //....
 
So as not impossible, but not future expandability, today if you want to change the operating time for each type of object, you must modify many places.

From the perspective of the object itself to think it over, one of the objects in the house, the objects, said: "Do not judge a painstaking outside the house, now that you do not know who I am, then you come visit me well, You tell me who I am, that way you know how to do to me! "

with a program to implement the above description:
  • IElement.java
public interface IElement { 
    public void accept(IVisitor visitor); 
} 

  • ElementA.java
public class ElementA implements IElement { 
    public void accept(IVisitor visitor) { 
        visitor.visit(this); 
    }

    public void operationA() { 
        System.out.println(
              "do A's job....such-and-such...."); 
    } 
} 

  • ElementB.java
public class ElementB implements IElement { 
    public void accept(IVisitor visitor) { 
        visitor.visit(this); 
    }

    public void operationB() { 
        System.out.println(
           "do B's job....such-and-such...."); 
    }
} 

  • ElementC.java
public class ElementC implements IElement { 
    public void accept(IVisitor visitor) { 
        visitor.visit(this); 
    }

    public void operationC() { 
        System.out.println(
            "do C's job....such-and-such...."); 
    } 
} 

  • IVisitor.java
public interface IVisitor { 
    public void visit(ElementA element); 
    public void visit(ElementB element); 
    public void visit(ElementC element); 
}  

  • VisitorA.java
public class VisitorA implements IVisitor { 
    public void visit(ElementA element) { 
        element.operationA(); 
    }

    public void visit(ElementB element) { 
        element.operationB(); 
    }

    public void visit(ElementC element) { 
        element.operationC(); 
    } 
}  

  • Main.java
public class Main { 
    public static void main(String[] args) { 
        // know nothing about their type 
        // after storing them into Element array 
        IElement[] list = {new ElementA(), 
                           new ElementB(), 
                           new ElementC()}; 

        IVisitor visitor = new VisitorA();

        for (int i=0; i < list.length; i++) 
            list[i].accept(visitor); 
    } 
} 

Visitor access is based on overload to complete, items for every implementation of IElement, it accepts IVisitor to access it, the accept () method, IVisitor use the correct method to access IElement (obvious, so you can rely on a different part the function name, or overload to achieve), and () made in the corresponding operations on IElement the visit, if you want to replace the operation of each IElement today, as long as the replacement IVisitor type of object on it, that is, this line:
 IVisitor new new VisitorA visitor = // (); 
 // replace a IVisitor, you can replace all of the operations
 // without modifying multiple places
 IVisitor visitor = new VisitorB (); 
 

To give an actual example, suppose VisitorA just a lazy salesman Well, today there is a more diligent salesman VisitorB, after visiting IElement, IElement will make more operations to achieve VisitorB in the program, as long as Add a VisitorB category will be able to:
  • VisitorB.java
public class VisitorB implements IVisitor { 
    public void visit(ElementA element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationA(); 
        System.out.println(
            "I want to do some extra work on A...."); 
    }

    public void visit(ElementB element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationB(); 
        System.out.println(
                   "I want to do some extra work on B...."); 
    }

    public void visit(ElementC element) { 
        System.out.println("VisitorB is a hard worker...."); 
        element.operationC(); 
        System.out.println(
                  "I want to do some extra work on C...."); 
    } 
} 

Main change to demonstrate:
  • Main.java
public class Main { 
    public static void main(String[] args) { 
        IElement[] list = {new ElementA(), 
                           new ElementB(), 
                           new ElementC()}; 

        System.out.println("visitorA is coming......."); 
        IVisitor visitorA = new VisitorA(); 
        for (int i=0; i < list.length; i++) 
           list[i].accept(visitorA);

        System.out.println("\nvisitorB is coming......."); 
        IVisitor visitorB = new VisitorB(); 
        for (int i=0; i < list.length; i++) 
            list[i].accept(visitorB); 
    } 
} 

In the example of System.out.println (); just a hint, it could also be your direct call for additional methods of IElement. 

Visitor mode UML class diagram the following structure:


In Java World has an article, mention can use reflection to improve the elasticity when the use of visitors, who are interested can refer to further Reflect ON at The Visitor Design pattern .

Reproduced in: https: //www.cnblogs.com/moiyer/archive/2011/08/10/2316168.html

Guess you like

Origin blog.csdn.net/weixin_34026484/article/details/94693164