访问者模式:表示作用于某对象结构的个元素的操作.它使你在不改变各元素的类的前提下定义作用于这些元素的新操作.
访问者模式的适用场景:有比较稳定的数据结构,又有易于变化的算法的话,使用反复问这模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易.
访问者模式的优缺点:
- 优点:增加新的操作容易,因为增加新的操作就意味着增加一个新的访问者.访问者模式将有关的行为集中到一个访问者对象中.
- 缺点:访问者模式使得增加新的数据结构变得苦难了.
访问者模式结构图:
代码实现:
1 package com.cgj.pattern.visitor; 2 3 /** 4 * Visitor接口 5 */ 6 public interface Action { 7 8 // 得到男人结论或反应 9 public abstract void getManConclusion(Man concreteElement); 10 11 // 得到女人的结论或反应 12 public abstract void getWomanConclusion(Woman concreteElement); 13 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * Element接口:定义一个访问的方法,它以一个访问者为参数 5 */ 6 public interface Person { 7 8 // 他是用来获得Visitor对象的 9 public abstract void accept(Action visitor); 10 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 具体的Element类 5 */ 6 public class Man implements Person { 7 8 // visitor给出访问的结果 9 @Override 10 public void accept(Action visitor) { 11 visitor.getManConclusion(this); 12 } 13 14 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 具体的Element类 5 */ 6 public class Woman implements Person { 7 8 // visitor给出访问的结果 9 @Override 10 public void accept(Action visitor) { 11 visitor.getWomanConclusion(this); 12 } 13 14 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 具体的访问者,实现每个由Visitor声明的操作. 5 * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类. 6 */ 7 public class Success implements Action { 8 9 @Override 10 public void getManConclusion(Man concreteElement) { 11 System.out.println("男人成功时,背后多半有一个伟大的女人."); 12 13 } 14 15 @Override 16 public void getWomanConclusion(Woman concreteElement) { 17 System.out.println("女人成功时,背后大多有一个不成功的男人."); 18 19 } 20 21 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 具体的访问者,实现每个由Visitor声明的操作. 5 * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类. 6 */ 7 public class Failing implements Action { 8 9 @Override 10 public void getManConclusion(Man concreteElement) { 11 System.out.println("男人失败时,闷头喝酒谁也不用劝."); 12 13 } 14 15 @Override 16 public void getWomanConclusion(Woman concreteElement) { 17 System.out.println("女人失败时,眼泪汪汪,谁也劝不了."); 18 19 } 20 21 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 具体的访问者,实现每个由Visitor声明的操作. 5 * 每个操作实现算法的一部分,而该算法片段乃是对应于结构中对象的类. 6 */ 7 public class Amativeness implements Action { 8 9 @Override 10 public void getManConclusion(Man concreteElement) { 11 System.out.println("男人恋爱时,凡是不懂也要装懂."); 12 13 } 14 15 @Override 16 public void getWomanConclusion(Woman concreteElement) { 17 System.out.println("女人恋爱时,遇事懂也装作不懂."); 18 19 } 20 21 }
1 package com.cgj.pattern.visitor; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 /** 7 * 能枚举它的元素,可以提供一个高层的接口以允许访问者访问他的元素. 8 */ 9 public class ObjectStructure { 10 11 private List<Person> elements = new ArrayList<Person>(); 12 13 public boolean add(Person element) { 14 return elements.add(element); 15 } 16 17 public boolean detach(Person element) { 18 return elements.remove(element); 19 } 20 21 // 枚举所有元素 22 public void display(Action visitor) { 23 for (Person element : elements) { 24 element.accept(visitor); 25 } 26 } 27 }
1 package com.cgj.pattern.visitor; 2 3 /** 4 * 首先在display函数中将具体的状态传递给Man类完成第一次分派, 5 * 然后Man调用作为参数的状态类中的getManConslusion函数同时将自身 6 * 作为参数传递进去,这便完成了第二次分派. 7 */ 8 public class Test { 9 10 public static void main(String[] args) { 11 ObjectStructure structure = new ObjectStructure(); 12 13 structure.add(new Man()); 14 structure.add(new Woman()); 15 16 System.out.println("成功时的反应"); 17 structure.display(new Success()); 18 19 System.out.println("失败时的反应"); 20 structure.display(new Failing()); 21 22 System.out.println("恋爱时的反应"); 23 structure.display(new Amativeness()); 24 } 25 26 }
(本随笔参考了程杰老师的<<大话设计模式>>)
时间: 2024-11-10 01:19:13