问题
不知道大家还记不记得外观模式中的接待经理,如果不记得的话,请参考设计模式之外观模式-与单一职责的PK(Facade)。接待经理负责和顾客沟通,同时和销售,收银,组装,打包等等对接,来提供给顾客最好的服务。但是呢,今天我需要安排他去参加一个全天会议,那店里没他可不行啊,那这怎么办呢?我只好通过代理模式来解决这个问题。
简介
首先我们先思考这个问题该怎么解决?我的解决方案是给他请一个秘书,一方面缓解其平时的工作压力,控制并非所有事项都去找接待经理;一方面防止其不在的时候,可以临时代理其工作。所以代理模式的主要作用就是代理对象,使用者需要通过代理访问;访问控制,控制使用者访问权限。这里有需要解释的一点是:代理模式是对对象的代理,所以代理类中必须有实体对象,而秘书的例子是直接变成了代理对象,是因为这样更贴近现实。可以理解成,秘书变成了接待经理,同时又代理了接待经理。
实现
定义经理的职责
public interface ManagerDuty {
void buy(String demand, int amount);
void attendMeeting();
}
经理职责实现
public class Manager implements ManagerDuty {
private String name;
public Manager(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void buy(String demand, int amount) {
System.out.println("manager " + name + " get the " + demand + " computer and give to custom");
}
@Override
public void attendMeeting() {
System.out.println(name + " attend meeting");
}
}
代理经理
public class ProxyManager implements ManagerDuty {
private Manager manager;
public ProxyManager(Manager manager) {
this.manager = manager;
}
@Override
public void buy(String demand, int amount) {
manager.buy(demand, amount);
}
@Override
public void attendMeeting() {
if (manager.getName().equalsIgnoreCase("peter")) {
System.out.println("peter can not attend meeting");
} else {
manager.attendMeeting();
}
}
}
执行类
public static void main(String[] args) {
Manager manager = new Manager("peter");
Manager manager1 = new Manager("james");
ProxyManager proxyManager = new ProxyManager(manager);
ProxyManager proxyManager1 = new ProxyManager(manager1);
proxyManager.buy("game", 1000);
proxyManager1.buy("design", 1000);
proxyManager.attendMeeting();
proxyManager1.attendMeeting();
}
执行结果
manager peter get the game computer and give to custom
manager james get the design computer and give to custom
peter can not attend meeting
james attend meeting
从执行结果即可看出:任何经理的工作都不能直接调用经理去执行,而必须通过代理经理,代理经理再调用经理去完成工作,另外就是代理经理也做到了访问控制,在一些场景下,不能执行经理的工作。
总结
代理模式和外观模式在学习过程中,会比较疑惑。这两个感觉差不多,都是在调用者和执行者之间添加中间层,外观模式本身避免了直接调用,同时也可以做到访问控制的功能。那这两者的区别核心在于应用场景
- 外观模式是在调用者和复杂系统(包含多个子系统)之间的中间层,而代理模式是调用者和指定对象之间的中间层。
- 外观模式中外观类中的方法一般不会只调用某个子系统的方法,而是会合并多个方法,例如SDK的初始化方法,可能会调用多个子系统的初始化方法。而代理模式一般是直接调用代理对象的方法,除了某些需要加访问控制的方法。
- 外观模式中外观类一般都会有执行顺序,而代理类一般没有。
按照前面的举例,接待经理整合收银,打包等各条线以提供给顾客购买电脑的服务是外观模式,而现在顾客和秘书沟通,秘书再安排接待经理的工作,则就是代理模式!