1. Proxy模式
代替别人进行工作,现在广泛应用在面向切面编程中。而且也不仅仅只做了代替工作,你会发现接下来示例程序中说的代理,其实是将“本人”的初始化进行了延迟,代理了一定的工作并不需要“本人”亲自去做,比如“告诉我你的名字”,这样的工作就已经交给了代理类去做。而现在使用的动态代理,面向切面编程中的代理类,是会在方法的前后做一些其他动作。
1.1 Proxy模式的类图
登场角色:
-
Subject(主体)
定义了主体的API,代理类和实际类都会实现该接口 -
Proxy(代理人)
RealSubject的代理角色 -
RealSubject(实际的主体)
被代理的实际角色 -
Client(请求者)
使用Proxy模式的类
1.2 类一览表
名字 | 说明 |
---|---|
Printable | 代理类和实际类的共同接口 |
Printer | 实际打印主体类 |
PrinterProxy | 代理打印类 |
Main | 测试类,代理模式的使用者 |
uml类图
Printable接口
package xin.ajay.proxy;
public interface Printable {
void setPrinterName(String name);//设置名字
String getPrinterName();//获取名字
void print(String msg);
}
Printer类
package xin.ajay.proxy;
public class Printer implements Printable {
private String name ;
@Override
public void setPrinterName(String name) {
this.name = name;
}
@Override
public String getPrinterName() {
return name;
}
@Override
public void print(String msg) {
System.out.println("=== " + name + " ===");
System.out.println(msg);
}
public Printer(String name) {
this.name = name;
heavyJob("Printer的实例生成中(" + name +")");
}
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.print(".");
}
System.out.println("结束");
}
}
PrinterProxy类
package xin.ajay.proxy;
public class PrinterProxy implements Printable{
private String name;
private Printer real;
public PrinterProxy(){}
public PrinterProxy(String name){
this.name = name;
}
public synchronized void setPrinterName(String name){
if(real != null){
real.setPrinterName(name);
}
this.name = name;
}
public String getPrinterName(){
return name;
}
public void print(String msg){
realize();
real.print(msg);
}
public synchronized void realize(){
if(real == null){
real = new Printer(name);
}
}
}
Main类
package xin.ajay.proxy;
public class Main {
public static void main(String[] args) {
PrinterProxy p = new PrinterProxy("Alice");
System.out.println("现在的名字是 " + p.getPrinterName() + "。");
p.setPrinterName("Bob");
System.out.println("现在的名字是 "+ p.getPrinterName() + "。");
p.print("Hello,World.");
}
}
鸣谢:
GoF《设计模式》和结城浩的《图解设计模式》