(二十一)访问者模式
对已存在的类进行扩展,通常需要增加方法,但是如果需要的行为与现有的对象模型不一致,或者无法修改现有代码。在这种情况下,不更改类的层次结构,就无法扩展该层次结构的行为。如果运用了访问者模式,就可以支持开发人员扩展该类层次结构的行为。
和解释器模式一样,访问者模式通常是基于合成模式的。
访问者模式在不改变类层次结构的前提下,对该层次结构进行扩展。
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维护。