(二十一)访问者模式
对已存在的类进行扩展,通常需要增加方法,但是如果需要的行为与现有的对象模型不一致,或者无法修改现有代码。在这种情况下,不更改类的层次结构,就无法扩展该层次结构的行为。如果运用了访问者模式,就可以支持开发人员扩展该类层次结构的行为。
和解释器模式一样,访问者模式通常是基于合成模式的。
访问者模式在不改变类层次结构的前提下,对该层次结构进行扩展。
interface Visitor{ public void visit(VisiSubject sub); } interface VisiSubject{ public void accept(Visitor visitor); public String getSubject(); } class MyVisitor implements Visitor{ public void visit(VisiSubject sub){ System.out.println("visitor MyVisitor:"+sub.getSubject()+""); } } class MyVisitor2 implements Visitor{ public void visit(VisiSubject sub){ System.out.println("visitor MyVisitor2:"+sub.getSubject()+""); } } class MyVisiSubject implements VisiSubject{ public void accept(Visitor visitor) { visitor.visit(this); } public String getSubject() { return "MyVisiSubject"; } } class MyVisiSubject2 implements VisiSubject{ public void accept(Visitor visitor) { visitor.visit(this); } public String getSubject() { return "MyVisiSubject2"; } } public class VisitorTest { public static void main(String[] args){ Visitor visitor = new MyVisitor2(); VisiSubject sub = new MyVisiSubject2(); sub.accept(visitor); } }
访问者模式是否是一个好的选择,取决于系统变化的特征:如果层次结构稳定,变化的是行为那么就是一个好的选择。如果行为稳定,层次结构总是变化,就不是一个好的选择了。因为你需要更新现有的访问者类,使得他们可以支持新的节点类型。
与任何模式一样,访问者模式不是必须的:如果需要使用该模式,就应该物尽其用。判断是否使用访问者模式,最好满足以下条件:
节点类型的集合是稳定的。
共同发生的变化是为不同的节点添加新的功能。
新功能必须适用于所有节点类型。
小结:
访问者模式使你可以在不改变类层次结构的前提下,为该结构增加新的行为。该模式的机制包括为访问者定义一个接口,为层次关系中的所有访问者增加一个accept()方法。accept()方法使用双重委派技术,将其调用委派给访问者。类层次结构中的对象可以根据其类型调用核实的visit()方法。
(二十二)中介者模式
面对对象开发要求尽可能恰当的分配职责,要求对象能够独立的完成自己的任务。观察者模式通过最小化对象与对象之间的职责交互,从而支持职责的合理分配。当对象间的交互趋向复杂,而每个对象都需要知道其他对象的情况时,提供一个集中地控制权是很有用的。当相关对象的交互逻辑独立于对象的其他行为时,职责的集中同样有用。
中介者模式的意图是定义一个对象,封装一组对象的交互,从而降低对象间的耦合度,避免了对象间的显式引用,并且可以独立地改变对象的行为。
interface Mediator{ public void createMediator(); public void workAll(); } abstract class MUser{ private Mediator mediator; public Mediator getMediator(){ return mediator; } public MUser(Mediator mediator){ this.mediator = mediator; } public abstract void work(); } class User1 extends MUser{ public User1(Mediator m){ super(m); } public void work(){ System.out.println("User1"); } } class User2 extends MUser{ public User2(Mediator m){ super(m); } public void work(){ System.out.println("User2"); } } class MyMediator implements Mediator{ private MUser user1; private MUser user2; public MUser getUser1() { return user1; } public MUser getUser2() { return user2; } @Override public void createMediator() { user1 = new User1(this); user2 = new User2(this); } @Override public void workAll() { user1.work(); user2.work(); } } public class MediatorTest { public static void main(String[] args){ Mediator m = new MyMediator(); m.createMediator(); m.workAll(); } }MUser类统一接口,User1和User2分别是不同的对象,两者之间有关联,如果不采用中介者模式,则需要两者相互持有引用,为了解耦引入中介者模式,Mediator为接口,MyMediator为实现类,持有user1跟user2,这两个类相互独立,只需要维持和Mediator之间的联系,剩下的由MyMediator维护。