目录
1.Proxy模式
1.1 作用
Proxy是代理人的意思,它指的是代替别人进行工作的人。只有当代理人遇到自己无法解决的事情才会去找本人解决问题。
1.2 示例程序
1.2.1 示例程序类图
1.2.2 Printable接口
//该接口为了使本人和代理具有一致性
public interface Printable {
public abstract void setPrinterName(String name);//设置名字
public abstract String getPrinterName();//获取名字
public abstract void print(String string);//显示文字,打印输出
}
1.2.3 Printer类
//表示本人的类
public class Printer implements Printable{
private String name;
public Printer() {
heavyJob("正在生成Printer的实例");
}
public Printer(String name) {
this.name = name;
heavyJob("正在生成Printer的实例");
}
@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);
}
public 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.print(".");
}
System.out.println("结束。");
}
}
1.2.4 PrinterProxy类
//表示代理人的类
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);
}
}
}
1.2.5 Main类
public class Main {
public static void main(String[] args) {
Printable p = new PrinterProxy("Alice");
System.out.println("现在的名字是" + p.getPrinterName() + "。");
p.setPrinterName("Bob");
System.out.println("现在的名字是" + p.getPrinterName() + "。");
p.print("Hello World!");
}
}
输出为:
1.2.6 示例程序时序图
1.3 Proxy模式中的角色
- Subject(主体):该角色定义了使Proxy角色和RealSubject角色之间具有一致性的接口。上述的Printable接口。
- Proxy(代理人):该角色会尽量处理来自Client角色的请求,只有当自己不能处理时,它才会将工作交给RealSubject角色。Proxy角色只有在必要时才会生成RealSubject角色。Proxy角色实现了在Subject角色中定义的接口API。上述的PrintProxy类。
- RealSubject(实际的主体):本人RealSubject角色会在代理人Proxy角色无法胜任工作时出场。也实现了Subject角色中定义的接口API。上述的Printer类。
- Client(请求者):使用Proxy模式的角色。
- Proxy模式的类图:
1.4 其他特点
- 可以通过使用代理人来提升处理速度。比如在示例程序中,我们成功地将耗时处理(生成实例的处理)推迟至print方法被调用后才进行。
- 可以有多个代理人,即改变在Printable接口中定义的那些方法,但是不论怎么改变,都不必修改Printer类(本人)。
- 代理类具有透明性。对于Main类来说,无论是直接使用Printer类还是通过PrinterProxy类间接地使用Printer类都可以。
- Http代理就是代理模式的一种体现。Http代理是指位于Http服务器(Web服务器)和Http客户端(Web浏览器)之间,为Web页面提供高速缓存等功能的软件。
- 各种Proxy模式:
- Virtual Proxy(虚拟代理):只有当真正需要实例时,它才生成和初始化实例。
- Remote Proxy(远程代理):可以让我们完全不必在意RealSubject角色是否在远程网络上,可以如同它在自己身边一样透明性地调用它的方法。
- Access Proxy:用于在调用RealSubject角色的功能时设置访问限制。
根据图解设计模式书籍进行整理。