访问者模式(Visitor Pattern)中元素的执行算法可以随着访问者改变而改变。 元素对象已接受访问者对象,这样访问者对象就可以处理元素对象上的操作。 优点: 1. 符合单一职责原则。 2. 优秀的扩展性。 3. 灵活性。 缺点: 1. 具体元素对访问者公布细节,违反了迪米特原则。 2. 具体元素变更比较困难。 3. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。
1. 访问者模式
package com.andrew.pattern0309.visitor.model01; public interface ComputerPart { public void accept(ComputerPartVisitor computerPartVisitor); }
package com.andrew.pattern0309.visitor.model01; public class Keyboard implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } } package com.andrew.pattern0309.visitor.model01; public class Monitor implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } } package com.andrew.pattern0309.visitor.model01; public class Mouse implements ComputerPart { @Override public void accept(ComputerPartVisitor computerPartVisitor) { computerPartVisitor.visit(this); } } package com.andrew.pattern0309.visitor.model01; public class Computer implements ComputerPart { ComputerPart[] parts; public Computer() { parts = new ComputerPart[] {new Mouse(), new Keyboard(), new Monitor()}; } @Override public void accept(ComputerPartVisitor computerPartVisitor) { for (int i = 0; i < parts.length; i++) { parts[i].accept(computerPartVisitor); } computerPartVisitor.visit(this); } }
package com.andrew.pattern0309.visitor.model01; public interface ComputerPartVisitor { public void visit(Computer computer); public void visit(Mouse mouse); public void visit(Keyboard keyboard); public void visit(Monitor monitor); }
package com.andrew.pattern0309.visitor.model01; public class ComputerPartDisplayVisitor implements ComputerPartVisitor { @Override public void visit(Computer computer) { System.out.println("Displaying Computer."); } @Override public void visit(Mouse mouse) { System.out.println("Displaying Mouse."); } @Override public void visit(Keyboard keyboard) { System.out.println("Displaying Keyboard."); } @Override public void visit(Monitor monitor) { System.out.println("Displaying Monitor."); } }
package com.andrew.pattern0309.visitor.model01; /** * 1. 访问者模式 * * @author andrew * @date 2018/08/20 */ public class Client { public static void main(String[] args) { ComputerPart computer = new Computer(); computer.accept(new ComputerPartDisplayVisitor()); } } 运行结果: Displaying Mouse. Displaying Keyboard. Displaying Monitor. Displaying Computer.
2. 访问者模式
package com.andrew.pattern0309.visitor.model02; public interface Element { public abstract void accept(IVisitor visitor); public abstract void doSomething(); }
package com.andrew.pattern0309.visitor.model02; public class ConcreteElement1 implements Element { public void accept(IVisitor visitor) { visitor.visit(this); }; public void doSomething() { System.out.println("这是元素1"); } } package com.andrew.pattern0309.visitor.model02; public class ConcreteElement2 implements Element { public void accept(IVisitor visitor) { visitor.visit(this); }; public void doSomething() { System.out.println("这是元素2"); } }
package com.andrew.pattern0309.visitor.model02; public interface IVisitor { public void visit(ConcreteElement1 el1); public void visit(ConcreteElement2 el2); }
package com.andrew.pattern0309.visitor.model02; public class Visitor implements IVisitor { @Override public void visit(ConcreteElement1 el1) { el1.doSomething(); } @Override public void visit(ConcreteElement2 el2) { el2.doSomething(); } }
package com.andrew.pattern0309.visitor.model02; import java.util.ArrayList; import java.util.List; import java.util.Random; public class ObjectStruture { public static ListgetList() { List list = new ArrayList (); Random ran = new Random(); for (int i = 0; i < 10; i++) { int a = ran.nextInt(100); if (a > 50) { list.add(new ConcreteElement1()); } else { list.add(new ConcreteElement2()); } } return list; } }
package com.andrew.pattern0309.visitor.model02; import java.util.List; /** * 2. 访问者模式 * * @author andrew * @date 2018/08/20 */ public class Client { public static void main(String[] args) { Listlist = ObjectStruture.getList(); for (Element e: list) { e.accept(new Visitor()); } } } 运行结果: 这是元素1 这是元素1 这是元素1 这是元素1 这是元素2 这是元素2 这是元素1 这是元素2 这是元素1 这是元素1