设计模式学习之代理模式
代理模式的定义:为其他对象提供一种代理以控制这个对象的访问,代理模式也叫做委托模式
代理模式通用类图如下:
Subject抽象主题角色:抽象主题类可以是抽象类或者接口。
RealSubject具体主题角色:叫做被委托对象,被代理对象,是业务逻辑的具体执行者
Proxy代理主题角色:叫做委托类、代理类。负责对真实角色的应用。
抽象角色:
/** * @author Lin * @Date 2018/1/5. */ public interface IGamePlayer { /** * 登录游戏 * @param user * @param password */ void login(String user,String password); /** * 杀怪 */ void killBoss(); /** * 升级 */ void upgrade(); }
被代理类的实现:
/** * @author Lin * @Date 2018/1/5. */ public class GamePlayer implements IGamePlayer { private String name = ""; public GamePlayer(String _name){ this.name = _name; } @Override public void login(String user, String password) { System.out.println("登录名为--" + user + "--的用户" + this.name + "登录成功!"); } @Override public void killBoss() { System.out.println(this.name + "在打怪!"); } @Override public void upgrade() { System.out.println(this.name + "又升一级!"); } }
代理类:
/** * @author Lin * @Date 2018/1/5. */ public class GamePlayerProxy implements IGamePlayer{ private IGamePlayer gamePlayer = null; /** * 构造函数指定对谁进行代练 * @param _gamePlayer */ public GamePlayerProxy(IGamePlayer _gamePlayer){ this.gamePlayer = _gamePlayer; } @Override public void login(String user, String password) { gamePlayer.login(user,password); } @Override public void killBoss() { gamePlayer.killBoss(); } @Override public void upgrade() { gamePlayer.upgrade(); } }
具体场景实现:
import java.util.Date; /** * @author Lin * @Date 2018/1/5. */ public class Client { /** * 普通自己玩游戏 * @param args */ /* public static void main(String[] args) { IGamePlayer player = new GamePlayer("H_Lin"); System.out.println("开始时间是:" + new Date()); player.login("User_Lin","123456"); player.killBoss(); player.upgrade(); System.out.println("游戏结束时间:" + new Date()); }*/ /** * 通过代练玩游戏 * @param args */ public static void main(String[] args) { //定义一个游戏玩家 IGamePlayer gamePlayer = new GamePlayer("张三"); //定义一个游戏代练 IGamePlayer proxy = new GamePlayerProxy(gamePlayer); System.out.println("开始时间是:" + new Date()); proxy.login("zhangSan","123456"); proxy.killBoss(); proxy.upgrade(); System.out.println("游戏结束时间:" + new Date()); } }
代理模式的优点:
- 职责清晰,真实角色就是实现实际的业务逻辑,不关系其他非本职责的事务,通过后期的代理完成一件事务。
- 高扩展性,具体的角色是可以随时变化的,只要它实现了接口,代理类可以在不做任何修改的情况下使用。
讲到代理就就必须提起动态代理了。什么是动态代理?动态代理是在实现阶段不用关心代理谁,而是在运行阶段才指定代理哪一个对象。
具体类图如下:
创建一个动态代理类:
/** * @author Lin * @Date 2018/1/5. */ public class GamePlayerTH implements InvocationHandler{ /** * 被代理的对象 */ Object obj = null; public GamePlayerTH(Object _obj){ this.obj = _obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(this.obj,args); return result; } }
具体实现场景:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Date; /** * @author Lin * @Date 2018/1/5. */ public class ClientTH { public static void main(String[] args) throws Exception{ //定义一个游戏玩家 IGamePlayer player = new GamePlayer("张三"); InvocationHandler handler = new GamePlayerTH(player); System.out.println("开始时间是:" + new Date()); ClassLoader cl = player.getClass().getClassLoader(); IGamePlayer proxy = (IGamePlayer) Proxy.newProxyInstance(cl,player.getClass().getInterfaces(),handler); proxy.login("zhangSan","123456"); proxy.killBoss(); proxy.upgrade(); System.out.println("游戏结束时间:" + new Date()); } }