定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。它将对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式。
优点:1.扩展性好。方便添加新的访问者。
2. 复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。
3.灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构。
4.符合单一职责原则。访问者模式把相关的行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。
缺点:1.破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
2.违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
3、具体访问者元素变更比较困难。
使用场景:不同的人使用不同的方法,避免使用if-else。
原理:把需要调用的方法的实现写在调用者自己的类中,被调用者依赖于调用者。
类图:
实例代码
访问者接口
1. public interface Visitor { 2. void visit(ConcreteElementA elementA); 3. void visit(ConcreteElementB elementB); 4. }
访问者实现
1. public class ConcreteVisitorA implements Visitor { 2. 3. 4. @Override 5. public void visit(ConcreteElementA elementA) { 6. 7. } 8. 9. @Override 10. public void visit(ConcreteElementB elementB) { 11. 12. } 13. }
1. public class ConcreteVisitorB implements Visitor { 2. @Override 3. public void visit(ConcreteElementA elementA) { 4. 5. } 6. 7. @Override 8. public void visit(ConcreteElementB elementB) { 9. 10. } 11. }
抽象元素 一般定义一个accept方法
1. public interface Element { 2. void accept(Visitor visitor); 3. }
具体元素
1. public class ConcreteElementA implements Element { 2. public void accept(Visitor visitor) { 3. System.out.println("访问A"); 4. visitor.visit(this); 5. } 6. }
1. public class ConcreteElementB implements Element { 2. public void accept(Visitor visitor) { 3. System.out.println("访问b"); 4. visitor.visit(this); 5. } 6. }
ObjectStructure存放具体元素对象的集合
1. public class ObjectStructure { 2. private List<Element> mElements = new ArrayList<>(); 3. 4. public void addElement(Element e) { 5. mElements.add(e); 6. } 7. 8. public void removeElement(Element e) { 9. mElements.remove(e); 10. } 11. 12. public void accpet(Visitor visitor) { 13. for (Element e : mElements) { 14. e.accept(visitor); 15. } 16. } 17. }
调用
1. ObjectStructure os = new ObjectStructure(); 2. os.addElement(new ConcreteElementA()); 3. os.addElement(new ConcreteElementB()); 4. //创建一个访问者 5. Visitor visitor = new ConcreteVisitorA(); 6. os.accpet(visitor);
代码
访问者接口
1. public interface Visitor { 2. 3. void visit(Cavalry cavalry); 4. 5. void visit(Infantry infantry); 6. }
访问者实现
1. public class liyunlong implements Visitor{ 2. 3. void visit(Cavalry cavalry){ 4. system.out.print("你们砍了多少鬼子啊" + cavalry.num) 5. } 6. 7. void visit(Infantry infantry){ 8. system.out.print("你们砍了多少鬼子啊" + infantry.num) 9. } 10. }
1. public class zhaogang implements Visitor{ 2. 3. void visit(Cavalry cavalry){ 4. system.out.print("你们背了多少条例啊" + cavalry.num) 5. } 6. 7. void visit(Infantry infantry){ 8. system.out.print("你们背了多少条例啊" + infantry.num) 9. } 10. }
具体元素接口
1. public interface Element { 2. 3. // 核心方法,接受Visitor的访问 4. public void accept(Visitor visitor); 5. }
具体元素实现
1. public class Cavalry implements Element { 2. 3. private int num; 4. //构造方法 5. public void accept(Visitor visitor) { 6. System.out.println("骑兵"); 7. visitor.visit(this); 8. } 9. }
1. public class Infantry implements Element { 2. private int num; 3. //构造方法 4. public void accept(Visitor visitor) { 5. System.out.println("步兵"); 6. visitor.visit(this); 7. } 8. }
管理类
1. public class ObjectStructure { 2. private List<Element> mElements = new ArrayList<>(); 3. 4. public void addElement(Element e) { 5. mElements.add(e); 6. } 7. 8. public void removeElement(Element e) { 9. mElements.remove(e); 10. } 11. 12. public void accpet(Visitor visitor) { 13. for (Element e : mElements) { 14. e.accept(visitor); 15. } 16. } 17. }
调用
1. ObjectStructure os = new ObjectStructure(); 2. os.addElement(new Cavalry(10)); 3. os.addElement(new Infantry(22)); 4. //创建一个访问者 5. Visitor visitor = new liyunlong(); 6. os.accpet(visitor);
经典实现场景
https://www.cnblogs.com/edisonchou/p/7247990.html