1 代理模式简介
代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。
简单地说,代理类具有和被代理类一样的方法,调用者通过调用代理类的方法间接调用了被代理类相同名字的方法,对于调用者来说,它不用察觉自己调用的是代理类的方法,感觉上仍然在调用被代理类的方法。对于被代理类来说,代理类可以在调用其方法前后做其他工作,比如写日志等。
比如张三拨打电话12345678给李四,这个是直接拨通没有代理,如果为张三提供一个代理王五,张三还是拨打12345678,但是是接通到王五那里,再由王五转接到李四,可能王五会在电话拨通前后做其他工作,比如记录下一些相关信息,但是对于张三要做的事情没有改变,在张三看来,还是直接拨通到李四,同样道理,李四也不会察觉
按照代理的创建时期可分两种:
静态代理类:在程序运行前,由程序员创建再编译成.class文件。
动态代理类:在程序运行时,运用反射机制动态创建而成。
1.1 静态代理
静态代理模式有三个角色: 1. 抽象接口 2. 代理类 3. 被代理类。
1.2 静态代理的实现
(1) 首先建一个StaticProxy包,所有程序都放在该包下。
(2) 建一个抽象接口(Subject.java)。
package StaticProxy;
public interface Subject {
public void print(String words);
}
(3) 建一个被代理类(RealSubject.java),需要实现Subject接口。
package StaticProxy;
public class RealSubject implements Subject{
public void print(String words) {
System.out.println("被代理的人郭襄说:"+words);
}
}
(4)建一个代理类(ProxySubject.java),需要实现Subject接口
package StaticProxy;
public class ProxySubject implements Subject{
private Subject s;
//传进要被代理的类的对象
public ProxySubject(Subject s){
this.s=s;
}
public void print(String words) {
System.out.println("我是代理,我的名字叫黄蓉!");
//调用实际的被代理的方法
s.print(words);
System.out.println("黄蓉代理完毕!");
}
}
(5) 建一个客户端程序(TestSubject.java)测试。
package StaticProxy;
public class TestSubject {
public static void main(String []args){
Subject sub1=new RealSubject();//创建真实对象(被代理对象)
Subject sub2=new ProxySubject(sub1);//创建代理对象,把被代理对象传进去
sub2.print("你好!"); //调用代理方法
}
}
运行输出:
我是代理,我的名字叫黄蓉!
被代理的人郭襄说:你好!
黄蓉代理完毕!
从输出可以看出,在真实对象的print方法被调用前后,代理对象都做了其他操作,在真实应用中,我们可以用代理类来编写日志、过滤信息等。
对于客户端来说,它只对接口Subject编程,提高了代码的可维护和可升级性。
(6) 我们还可以创建多重代理,即代理的代理,我们编写一个代理类(Proxy2Subject.java),同样需要实现Subject接口。
package StaticProxy;
public class Proxy2Subject implements Subject{
private Subject s;
public Proxy2Subject(Subject s){
this.s=s;
}
public void print(String words) {
System.out.println("我是代理,我的名字叫郭靖!");
//调用实际的被代理的方法
s.print(words);
System.out.println("郭靖代理完毕!");
}
}
(7)再修改一下客户端程序(TestSubject.java)。
package StaticProxy;
public class TestSubject {
public static void main(String []args){
Subject sub1=new RealSubject();//创建真实对象(被代理对象)
Subject sub2=new ProxySubject(sub1);//创建代理对象,把被代理对象传进去
Subject sub3=new Proxy2Subject(sub2);//创建代理对象,把被代理对象传进去
sub3.print("你好!"); //调用代理方法
}
}
运行输出:
我是代理,我的名字叫郭靖!
我是代理,我的名字叫黄蓉!
被代理的人郭襄说:你好!
黄蓉代理完毕!
郭靖代理完毕!
从输出可以看到,郭靖就是黄蓉的代理,黄蓉是郭襄的代理,实现了多重代理。
(7)最后,我们再看一下这两种情况的UML图。
图1.1 只有一个代理
图1.2 具有两个代理
推荐文章:
浅析JAVA设计模式之代理模式(二)
http://blog.csdn.net/minidrupal/article/details/24888271
浅析JAVA设计模式之代理模式(三)
http://blog.csdn.net/minidrupal/article/details/24985737
浅析JAVA设计模式之代理模式(四)
http://blog.csdn.net/minidrupal/article/details/25058433
浅析JAVA设计模式之代理模式(五)
http://blog.csdn.net/minidrupal/article/details/25093563
浅析JAVA设计模式之代理模式(六)
http://blog.csdn.net/minidrupal/article/details/27948355
浅析JAVA设计模式之代理模式(七)
http://blog.csdn.net/minidrupal/article/details/28588507
Author: Piano
Introduction: 师者
Sign: 读书得可道之道,实践悟不可道之道