访问者模式(visitor)

# 一句话总结 访问者不同,结果不同 # 内容 不同访问者实现对相同数据集的不同的操作 # 场景 kpi考核:考核标准是相对稳定,但CEO和CTO的看重员工的点是不同的。 餐厅:餐厅的菜单和就餐方式是相对稳定的,但取就餐人员是每天变化的。 # 类图 ![image.png](https://upload-images.jianshu.io/upload_images/5359801-efc53f37c189436b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) # 代码示例 ```` // 抽象元素 public interface IElement { void accept(IVisitor visitor); } // 具体元素 public class ConcreteElementA implements IElement { public void accept(IVisitor visitor) { visitor.visit(this); } public String operationA() { return this.getClass().getSimpleName(); } } // 具体元素 public class ConcreteElementB implements IElement { public void accept(IVisitor visitor) { visitor.visit(this); } public int operationB() { return new Random().nextInt(100); } } // 结构对象 public class ObjectStructure { private List list = new ArrayList (); { this.list.add(new ConcreteElementA()); this.list.add(new ConcreteElementB()); } public void accept(IVisitor visitor) { for (IElement element : this.list) { element.accept(visitor); } } } // 抽象访问者 public interface IVisitor { void visit(ConcreteElementA element); void visit(ConcreteElementB element); } // 具体访问者 public class ConcreteVisitorA implements IVisitor { public void visit(ConcreteElementA element) { String result = element.operationA(); System.out.println("result from " + element.getClass().getSimpleName() + ": " + result); } public void visit(ConcreteElementB element) { int result = element.operationB(); System.out.println("result from " + element.getClass().getSimpleName() + ": " + result); } } // 具体访问者 public class ConcreteVisitorB implements IVisitor { public void visit(ConcreteElementA element) { String result = element.operationA(); System.out.println("result from " + element.getClass().getSimpleName() + ": " + result); } public void visit(ConcreteElementB element) { int result = element.operationB(); System.out.println("result from " + element.getClass().getSimpleName() + ": " + result); } } public class Test { public static void main(String[] args) { ObjectStructure collection = new ObjectStructure(); System.out.println("ConcreteVisitorA handle elements:"); IVisitor visitorA = new ConcreteVisitorA(); collection.accept(visitorA); System.out.println("------------------------------------"); System.out.println("ConcreteVisitorB handle elements:"); IVisitor visitorB = new ConcreteVisitorB(); collection.accept(visitorB); } } ```` 运行结果 ![image.png](https://upload-images.jianshu.io/upload_images/5359801-ac5747882e619e44.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) #访问者模式中的两次动态分派 ###静态分派和动态分派 静态类型是List即变量的生命类型,实际类型是对象的类型 ```` List str = new ArrayList() ```` 静态分派指根据静态类型进行分派,在编译时期完成如重载方法的分配。 动态分派指根据实际类型进行分派,在运行时期完成如多态。 ###访问者模式中的两次动态分派 #####第一次分配 根据element的具体对象来决定调用具体元素对象的方法。 ```` public void accept(IVisitor visitor) { for (IElement element : this.list) { element.accept(visitor); } } ```` #####第二次分配 根据IVisitor的具体对象来确定调用哪个IVisitor具体实现方法。 ```` public void accept(IVisitor visitor) { visitor.visit(this); } ````

你可能感兴趣的:(访问者模式(visitor))