1. 概述
在面向对象编程的过程中,“本人”和“代理人”都是对象。如果“本人”对象太忙的了,有些工作自己无法亲自完成,就将其交给“代理人”对象负责。
在处理请求的时候“代理人”会尽量处理客户的请求,只有自己不能处理时,才会把工作交给“本人”。例如:可以在“代理人”判断请求的是否合法和处理异常等,“本人”要实现线程同步,则可以在“代理人”中实现同步,具体的请求处理在交给“本人”处理。
2. 实例程序
一个接口类,本人类和代理类都需要实现这一个接口。
Printable.java , 接口类。
package proxy;
public interface Printable {
/**
* 设置名字
* @param name 名字
*/
public abstract void setPrinterName(String name);
/**
* 获取名字
* @return 获取的名字字符串
*/
public abstract String getPrinterName();
/**
* 打印 string 字符串
* @param string 将要被打印的字符串
*/
public abstract void print(String string);
}
本人类,Printer.java:
package proxy;
public class Printer implements Printable {
private String name; // 名字
public Printer(String name) {
this.name = name;
heavyJob("Printer实例正在生成中 (" + name + ")");
}
@Override
public void setPrinterName(String name) {
this.name = name;
}
@Override
public String getPrinterName() {
return this.name;
}
@Override
public void print(String string) {
System.out.println("=== " + name + " ===");
System.out.println(string);
}
private void heavyJob(String msg) {
System.out.println(msg);
for (int i=0; i<5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(".");
}
System.out.println("结束。");
}
}
代理类代替本人类实现setPrinterName和getPrinterName两个方法,只有在需要调用本人类“独有的方法print”才去创建本人类实例,PrinterProxy.java:
package proxy;
public class PrinterProxy implements Printable{
private String name; // 名字
private Printer real; //本人
public PrinterProxy() {
}
public PrinterProxy(String name) {
this.name = name;
}
@Override
public synchronized void setPrinterName(String name) {
if (real != null) {
real.setPrinterName(name);
}
this.name = name;
}
@Override
public String getPrinterName() {
return name;
}
@Override
public void print(String string) {
realize();
real.print(string);
}
private synchronized void realize() {
if (real == null) {
real = new Printer(name);
}
}
}
示例的UML图如下所示:
测试代码,Test.java:
package proxy;
public class Test {
public static void main(String args[]) {
Printable p = new PrinterProxy("Rose");
System.out.println("现在的名字是" + p.getPrinterName());
p.setPrinterName("Jack");
System.out.println("现在的名字是" + p.getPrinterName());
p.print("Hello Proxy!");
}
}
运行截图如下所示:
参考文献:
- 图解设计模式 - 结成浩著、杨文轩译 - 人民邮电出版社