一.小结
- 定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
- 优点:1.符合单一职责原则 2.优秀的扩展性 3.灵活性高
- 缺点:1.具体元素对访问者公布细节,违反了迪米特原则 2.具体元素的变更比较困难 3.访问者依赖了具体类,违背了依赖倒置原则
- 使用场景:业务规则要求遍历多个不同的对象
- 通用UML图
二.例子
有一些公司要求程序员写周报总结,交给老板察看。对于研发组,老板一般只关心研发组长的周报,而研发组长会检查每个组员的周报。针对这个周报的情景,可以采用访问者模式。
-
元素接口
public interface IEmployee { void work(); void accept(IVisitor visitor); }
-
具体的元素
public class CommDeveloper implements IEmployee { @Override public void work() { System.out.println("普通工程师,修复Bug,需求开发..."); } @Override public void accept(IVisitor visitor) { visitor.visit(this); } } public class DeveloperLeader implements IEmployee { @Override public void work() { System.out.println("软件部主管,开会,安排任务..."); } @Override public void accept(IVisitor visitor) { visitor.visit(this); } }
-
访问者接口
public interface IVisitor { void visit(CommDeveloper commDeveloper); void visit(DeveloperLeader developerLeader); }
-
具体的访问者
public class BossVisitor implements IVisitor { @Override public void visit(CommDeveloper commDeveloper) { commDeveloper.work(); } @Override public void visit(DeveloperLeader developerLeader) { developerLeader.work(); } }
-
情景类
public class Client { public static void main(String[] args) { // 元素 CommDeveloper commDeveloper = new CommDeveloper(); DeveloperLeader developerLeader = new DeveloperLeader(); // 访问者 BossVisitor bossVisitor = new BossVisitor(); // 访问者访问元素 commDeveloper.accept(bossVisitor); developerLeader.accept(bossVisitor); } }