设计模式之代理模式

xiaoxiao2021-02-28  85

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

测试代码如下:

一、普通代理

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 { @Override public void login(String user, String psw) { System.out.println("登陆成功了..."); } @Override public void kill() { System.out.println("正在打野怪..."); } @Override public 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(); } } @Override public void login(String user, String psw) { this.realSubject.login(user, psw); } @Override public void kill() { this.realSubject.kill(); } @Override public 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; } @Override public void login(String user, String psw) { System.out.println("登陆成功了..."); } @Override public void kill() { System.out.println("正在打野怪..."); } @Override public 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; } @Override public void login(String user, String psw) { this.realSubject.login(user, psw); } @Override public void kill() { this.realSubject.kill(); } @Override public 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 { @Override public 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; } @Override public 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、测试结果

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

转载请注明原文地址: https://www.6miu.com/read-94732.html

最新回复(0)