代理模式是一种很常用的设计模式,其目的是对其他对象提供一种代理以控制对这个对象的访问。
代理模式又分为静态代理和动态代理,静态代理是在程序运行之前就已经存在了代理类,动态代理是程序运行中在内存中生成代理类。
代理模式存在的意义:代理模式是为了解决滥用继承的问题而生的,当想对某个类的功能进行扩充的时候可以使用继承或聚合,很明显用继承的话会造成类泛滥,还有一点就是继承是类具有很强的层级关系的情况下用才好,而紧紧对某个类进行功能的扩充就拿起继承的大刀明显的不合适,那么用聚合呢?聚合是一种松耦合的,用聚合创建的代理类就是静态代理,还有更好的代理是动态代理。
动态代理自己实现其实也很简单,不过JDK提供了方便的解决方案。
java.lang.reflect.InvocationHandler
java.lang.reflect.Proxy
这两个东东就是为动态代理而生的
Java代码
1.package design.proxy.hello;
2./**
3. * @author 作者 E-mail: jqsl2012@163.com
4. * @version 创建时间:2012-2-2 下午03:57:56 <br>
5. */
6.public interface Hello {
7. void say();
8.}
Java代码
1.package design.proxy.hello;
2.
3./**
4. * @author 作者 E-mail: jqsl2012@163.com
5. * @version 创建时间:2012-2-2 下午03:58:10 <br>
6. * 被代理的类
7. */
8.public class HelloImpl implements Hello {
9.
10. public void say() {
11. System.out.println("say");
12. }
13.}
Java代码
1.package design.proxy.hello;
2.
3.import java.lang.reflect.InvocationHandler;
4.import java.lang.reflect.Method;
5.import java.lang.reflect.Proxy;
6.
7./**
8. * @author 作者 E-mail: jqsl2012@163.com
9. * @version 创建时间:2012-2-2 下午03:54:45 <br>
10. * 动态代理
11. */
12.public class HelloProxy {
13. public static Object newProxyInstance(final Object target) {
14. InvocationHandler h = new InvocationHandler() {
15.
16. public Object invoke(Object proxy, Method method, Object[] args)
17. throws Throwable {
18. before();
19. Object result = method.invoke(target, args);
20. after();
21. return result;
22. }
23. };
24. return Proxy.newProxyInstance(target.getClass().getClassLoader(),
25. target.getClass().getInterfaces(), h);
26. }
27.
28. private static void before() {
29. System.out.println("before");
30. }
31.
32. private static void after() {
33. System.out.println("after");
34. }
35.}
Java代码
1.package design.proxy.hello;
2./**
3. * @author 作者 E-mail: jqsl2012@163.com
4. * @version 创建时间:2012-2-2 下午03:57:44 <br>
5. *
6. */
7.public class Test {
8. public static void main(String[] args) {
9. /*
10. * 代理模式
11. */
12. Hello proxy = (Hello) HelloProxy.newProxyInstance(new HelloImpl());
13. proxy.say();
14. }
15.}
-----------------------------分割线----------------------------------
上面是代理模式,其实装饰模式和代理模式极为相似
相同点:都是为被代理(被装饰)的类扩充新的功能。
不同点:代理模式具有控制被代理类的访问等性质,而装饰模式紧紧是单纯的扩充被装饰的类。所以区别紧紧在是否对被代理/被装饰的类进行了控制而已。
Java代码
1.package design.staticProxy;
2./**
3. * @author 作者 E-mail: jqsl2012@163.com
4. * @version 创建时间:2012-2-3 下午10:10:43 <br>
5. */
6.public interface InputStream {
7. void read();
8.}
Java代码
1.package design.staticProxy;
2./**
3. * @author 作者 E-mail: jqsl2012@163.com
4. * @version 创建时间:2012-2-3 下午10:11:16 <br>
5. */
6.public class FileInputStream implements InputStream{
7.
8. public void read() {
9. System.out.println("FileInputStream.read");
10. }
11.
12.}
Java代码
1.package design.staticProxy;
2.
3./**
4. * @author 作者 E-mail: jqsl2012@163.com
5. * @version 创建时间:2012-2-3 下午10:11:50 <br>
6. * 代理/装饰类具有和被代理/被装饰的类相同的接口
7. */
8.public class BufferedInputStream implements InputStream {
9. protected InputStream in;
10.
11. public BufferedInputStream(InputStream in) {
12. this.in = in;
13. }
14.
15. public void read() {
16. //加入控制代码就是代理,否则单纯的扩充功能就是装饰模式
17. if(true){
18. System.out.println("BufferedInputStream.read");
19. }
20. this.in.read();
21. }
22.}
Java代码
1.package design.staticProxy;
2.
3./**
4. * @author 作者 E-mail: jqsl2012@163.com
5. * @version 创建时间:2012-2-3 下午10:13:20 <br>
6. */
7.public class Test {
8. public static void main(String[] args) {
9. BufferedInputStream buffIn = new BufferedInputStream(new FileInputStream());
10. buffIn.read();
11. }
12.}
很明显,装饰模式和静态代理极为相似。设计模式里面有许多模式都看起来很相似,要区分估计得从目的上去区分了。 |