[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍代理模式,文章主题结构与上位一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk7
-------------------------------------------------------------------------------------------------------------------------------------
经典问题:
12306火车票代购,海淘网站代购,第三方中介代理平台等等。
思路分析:
要点一:调用方与被调用方无直接调用。
要点二:代理与被代理功能完全相同,对调用方而言无任何差异。
要点三:代理能够实现功能聚合。
示例工程:
错误写法:
创建Customer.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.base;
public class Customer {
public String Name;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
创建Ticket.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.base;
public class Ticket {
Customer mm;
public Ticket(Customer mm){
this.mm = mm;
}
public void getAirTicket(){
System.out.println(mm.Name+"AirTicket");
}
public void getTrainTicket(){
System.out.println(mm.Name+"TrainTicket");
}
public void getBusTicket(){
System.out.println(mm.Name+"BusTicket");
}
}
创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.base;
public class Window {
public static void main(String[] args) {
Customer ingo = new Customer();
ingo.Name = "ingo";
Ticket t = new Ticket(ingo);
t.getAirTicket();
t.getBusTicket();
t.getTrainTicket();
}
}
错误原因:
调用方与被调用方发生直接耦合关系。违反“开闭原则”。注:本例代码仅作说明使用。
推荐写法:
创建ConcreteGetTicket.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.one;
public class ConcreteGetTicket implements GetTicket {
Customer mm;
public ConcreteGetTicket(Customer mm){
this.mm = mm;
}
public void getAirTicket(){
System.out.println(mm.Name+"AirTicket");
}
public void getTrainTicket(){
System.out.println(mm.Name+"TrainTicket");
}
public void getBusTicket(){
System.out.println(mm.Name+"BusTicket");
}
}
创建Customer.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.one;
public class Customer {
public String Name;
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
}
创建GetTicket.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.one;
public interface GetTicket {
public void getAirTicket();
public void getTrainTicket();
public void getBusTicket();
}
创建Proxy.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.one;
public class Proxy implements GetTicket{
ConcreteGetTicket gg;
public Proxy(Customer mm){
gg = new ConcreteGetTicket(mm);
}
public void getAirTicket() {
// TODO Auto-generated method stub
gg.getAirTicket();
}
public void getTrainTicket() {
gg.getTrainTicket();
}
public void getBusTicket() {
gg.getBusTicket();
}
}
创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_proxy.one;
public class Window {
public static void main(String[] args) {
Customer ingo = new Customer();
ingo.Name = "ingo";
Proxy p = new Proxy(ingo);
p.getAirTicket();
p.getTrainTicket();
p.getBusTicket();
}
}
推荐原因:
符合“开闭原则”,修改真实的服务提供商,代理内部调整,对客户端完全透明。
解决某些应用场景下的无法直接访问的问题。
模式总结:
UML结构图:
概念总结:
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
组成部分:Subject(抽象父类),RealSubject(具体功能类),Proxy(代理类)三部分组成。
特别提醒:RealSubject与Proxy都需要实现Subject中定义的所有方法。
反思:
应用场景:
远程代理:为一个对象在不同的地址空间提供局部代表。隐藏该对象存在于不同地址空间的事实。如:远程访问调用。虚拟代理:根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真是对象。如:网页图片预览下载。
安全代理:控制真实对象访问时的权限。
智能指引:当调用真是的对象时,代理处理另一些事。如:数据统计,日志记录,逻辑检查等。
优点:
能够降低调用方与被调用方之间的耦合关系。
其他几种优点见前一项内容。
缺点:
代理部件,有可能会导致整个处理过程时间增长。
有些代理处理过程可能极为复杂,增加了设计开发难度。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---代理模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445