读书笔记 仅供参考
简述
Proxy, 代理模式,代替一些类进行工作。
角色和 UML
Subject
定义了使 Proxy 角色和 RealSubject 角色具有一致性的接口。
Proxy
角色会尽量处理来自 Client 角色的请求。只有当自己不能处理的时候,才会将工作交给 RealSubject 角色。Proxy 只会在必要时才会生成 RealSubject 角色。
RealSubject
在 Proxy 角色无法胜任工作的时候出场。
Client
使用 Proxy 模式的角色。
UML
例子
例程是一个代理打印机的程序,真正的打印机对象只有在执行打印(print)方法时才会真正的创建,之前的一些事情都是代理(Proxy)在做。
//用于使 PrinterProxy 和 Printer 具有一致性,担任 Subject 角色
public interface Printable {
void setPrinterName(String name);//设置打印机名字
String getPrinterName();//获得打印机名字
void print(String string);//显示文字
}
// 担任 RealSubject 角色,就是本人
public class Printer implements Printable {
private String name;
public Printer() {
heavyJob("正在生成 Printer 的实例");
}
public Printer(String name) {
this.name = name;
heavyJob("正在生成 Printer 的实例 (" + name + ")");
}
private void heavyJob(String msg) {
System.out.print(msg);
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
System.out.print(".");
}
System.out.println("结束。");
}
@Override
public void setPrinterName(String name) {
this.name = name;
}
@Override
public String getPrinterName() {
return name;
}
@Override
public void print(String string) {
System.out.println("=== " + name + " ===");
System.out.println(string);
}
}
// 扮演代理人角色,主要帮助 Printer 代理设置名字和获得名字这两个方法,只有当打印文字时才会创建
// Printer 对象
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);
}
}
}
public class Main {
public static void main(String[] args) {
Printable printer = new PrinterProxy("Alice");
System.out.println("现在的名字是 " + printer.getPrinterName() + "。");
printer.setPrinterName("Bob");
System.out.println("现在的名字是 " + printer.getPrinterName() + "。");
printer.print("Hello, world.");
}
}
结果
UML
要点
- 使用代理提升速度,就像网页中图片显示就使用了代理模式,读取图片会消耗比较大的资源,在用户还没有看到图片时先不加载,而是放一个代理图片,之后再加载。