设计模式之代理模式

来源:互联网 发布:药学在职研究生知乎 编辑:程序博客网 时间:2024/05/22 12:34

描述:场景是玩游戏打怪升级,这里的代理就是找一个代练玩家,比较常用到的代理模式有普通代理,强制代理以及动态代理,普通代理好比我自己(游戏玩家)直接找到代练玩家给他账号密码代练就可以了(做的事情无非就是登陆,打怪及升级),强制代理好比必须通过先找到游戏代练公司,代练公司有捆绑好的代练玩家帮你去代练。动态代理就是在程序运行过程中才会生成代理类,好处就是能够统一处理被代理对象的方法,比如在被代理对象的所有方法添加日志等。

测试代码如下:


一、普通代理

1、被代理对象接口

package com.java.commonproxy;public interface Subject {public void login(String user, String psw);public void kill();public void update();}

2、被代理对象接口的实现类

package com.java.commonproxy;public class RealSubject implements Subject {@Overridepublic void login(String user, String psw) {System.out.println("登陆成功了...");}@Overridepublic void kill() {System.out.println("正在打野怪...");}@Overridepublic void update() {System.out.println("账号升级了...");}}

3、代理类

package com.java.commonproxy;public class ProxySubject implements Subject {private Subject realSubject;public ProxySubject() {if(realSubject == null){realSubject = new RealSubject();}}@Overridepublic void login(String user, String psw) {this.realSubject.login(user, psw);}@Overridepublic void kill() {this.realSubject.kill();}@Overridepublic void update() {this.realSubject.update();}}

4、测试类

package com.java.commonproxy;public class CommonProxyTest {public static void main(String[] args) {ProxySubject proxy = new ProxySubject();proxy.login("zhangsan", "123456");proxy.kill();proxy.update();}}

5、测试结果

登陆成功了...正在打野怪...账号升级了...

二、强制代理

1、被代理对象接口

package com.java.forceproxy;public interface Subject {public void login(String user, String psw);public void kill();public void update();}

2、被代理对象接口实现类

package com.java.forceproxy;public class RealSubject implements Subject {private ProxySubject proxy;public Subject getProxy(){if(proxy == null){proxy = new ProxySubject(this);}return proxy;}@Overridepublic void login(String user, String psw) {System.out.println("登陆成功了...");}@Overridepublic void kill() {System.out.println("正在打野怪...");}@Overridepublic void update() {System.out.println("账号升级了...");}}

3、代理对象

package com.java.forceproxy;public class ProxySubject implements Subject {private Subject realSubject;public ProxySubject(Subject realSubject) {this.realSubject = realSubject;}@Overridepublic void login(String user, String psw) {this.realSubject.login(user, psw);}@Overridepublic void kill() {this.realSubject.kill();}@Overridepublic void update() {this.realSubject.update();}}

4、测试类

package com.java.forceproxy;public class ForceDynamicTest {public static void main(String[] args) {RealSubject subject = new RealSubject();Subject proxy = subject.getProxy();proxy.login("zhangshan", "123456");proxy.kill();proxy.update();}}

5、测试结果

登陆成功了...正在打野怪...账号升级了...

三、动态代理

UML类图



1、被代理对象接口

package com.java.dynamicproxy;public interface Subject {public void cry();}

2、被代理对象接口实现类

package com.java.dynamicproxy;public class RealSubject implements Subject {@Overridepublic void cry() {System.out.println("秦始皇哭了!");}}

3、动态代理类(只是生产一个代理对象,实际的调用并不是在这里)

package com.java.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {private Object target = null;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("方法调用前...");Object object = method.invoke(target, args);System.out.println("方法调用后...");return object;}}

4、实际对被代理对象方法的调用 InvocationHandler

package com.java.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class DynamicProxy<T> {@SuppressWarnings("unchecked")public static <T> T newInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler){return (T)Proxy.newProxyInstance(loader, interfaces, handler);}}

5、测试类

package com.java.dynamicproxy;public class DynamicProxyTest {public static void main(String[] args){Subject subject = new RealSubject();MyInvocationHandler handler = new MyInvocationHandler(subject);Subject proxy = DynamicProxy.newInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(), handler);proxy.cry();}}

6、测试结果

方法调用前...秦始皇哭了!方法调用后...


0 0
原创粉丝点击