本文共 3581 字,大约阅读时间需要 11 分钟。
在有些情况下,一个客户不能或者不想直接访问另一个对象,这时需要找一个中介帮忙完成某项任务,这个中介就是代理对象。例如,购买火车票不一定要去火车站买,可以通过 12306 网站或者去火车票代售点买。又如找女朋友、找保姆、找工作等都可以通过找中介完成。
在软件设计中,使用代理模式的例子也很多,例如,要访问的远程对象比较大(如视频或大图像等),其下载要花很多时间。还有因为安全原因需要屏蔽客户端直接访问真实对象,如某单位的内部数据库等。
代理模式(Proxy Pattern)的定义:
由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。代理模式(Proxy Pattern)的优点:
1.代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用; 2.代理对象可以扩展目标对象的功能; 3.代理模式能将客户端与目标对象分离,在一定程度上降低了系统的耦合度;代理模式(Proxy Pattern)的缺点:
1.在客户端和目标对象之间增加一个代理对象,会造成请求处理速度变慢; 2.增加了系统的复杂度;代理模式的结构比较简单,主要是通过定义一个继承抽象主题的代理来包含真实主题,从而实现对真实主题的访问,下面来分析其基本结构和实现方法。
代理模式的主要角色如下。
其结构图如图 1 所示。
代理模式的实现代码如下:
package proxy;public class ProxyTest{ public static void main(String[] args) { Proxy proxy=new Proxy(); proxy.Request(); }}//抽象主题interface Subject{ void Request();}//真实主题class RealSubject implements Subject{ public void Request() { System.out.println("访问真实主题方法..."); }}//代理class Proxy implements Subject{ private RealSubject realSubject; public void Request() { if (realSubject==null) { realSubject=new RealSubject(); } preRequest(); realSubject.Request(); postRequest(); } public void preRequest() { System.out.println("访问真实主题之前的预处理。"); } public void postRequest() { System.out.println("访问真实主题之后的后续处理。"); }}
程序运行的结果如下:
访问真实主题之前的预处理。访问真实主题方法...访问真实主题之后的后续处理。
【例】韶关“天街e角”公司是一家婺源特产公司的代理公司,用代理模式实现。
分析:本实例中的“婺源特产公司”经营许多婺源特产,它是真实主题,提供了显示特产的 display() 方法,可以用窗体程序实现。而韶关“天街e角”公司是婺源特产公司特产的代理,通过调用婺源特产公司的 display() 方法显示代理产品,当然它可以增加一些额外的处理,如包裝或加价等。客户可通过“天街e角”代理公司间接访问“婺源特产公司”的产品,图 2 所示是公司的结构图。
package proxy;import java.awt.*;import javax.swing.*;public class WySpecialtyProxy{ public static void main(String[] args) { SgProxy proxy=new SgProxy(); proxy.display(); }}//抽象主题:特产interface Specialty{ void display();}//真实主题:婺源特产class WySpecialty extends JFrame implements Specialty{ private static final long serialVersionUID=1L; public WySpecialty() { super("韶关代理婺源特产测试"); this.setLayout(new GridLayout(1,1)); JLabel l1=new JLabel(new ImageIcon("src/proxy/WuyuanSpecialty.jpg")); this.add(l1); this.pack(); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public void display() { this.setVisible(true); }}//代理:韶关代理class SgProxy implements Specialty{ private WySpecialty realSubject=new WySpecialty(); public void display() { preRequest(); realSubject.display(); postRequest(); } public void preRequest() { System.out.println("韶关代理婺源特产开始。"); } public void postRequest() { System.out.println("韶关代理婺源特产结束。"); }}
程序运行结果如图 3 所示。
在前面介绍的代理模式中,代理类中包含了对真实主题的引用,这种方式存在两个缺点。
转载地址:http://jcsqb.baihongyu.com/