<<1.0 普通代理>>
前言:通过打游戏的例子来分析普通代理模式的原理,打游戏的过程无非就是打怪升级,那么把这一过程系统化,如图所示:
微信截图_20180817172314.png
代码清单-游戏者接口
public interface IGamePlayer {
//登陆游戏
public void login(String user,String password);
//打怪,游戏主要乐趣
public void killBoss();
//升级
public void upgrade();
}
定义了游戏的三个简单方法分别是:登录游戏、打怪、升级;
代码清单-游戏者
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.print("登录用户名:" + user + "的用户" + this.name + "succes");
}
@Override
public void killBoss() {
System.out.print(this.name+"在打怪...");
}
@Override
public void upgrade() {
System.out.print(this.name+"又升级了...");
}
}
在实现类的构造函数中传递玩家的姓名,方便后期调式,通过这样的场景来模拟游戏的过程代码入下
代码清单
public class Client{
public static void main(String[] agrs) {
IGamePlayer iGamePlayer = new GamePlayer("test");
//记录开始时间
System.out.print("开始时间:"+System.currentTimeMillis());
//登录游戏
iGamePlayer.login("username","password");
//打怪
iGamePlayer.killBoss();
//升级
iGamePlayer.upgrade();
System.out.print("结束时间:"+System.currentTimeMillis());
}
}
输出结果:
开始时间:1534492600636
登录用户名:username的用户testsucces
test再打怪...
test又升级了...
结束时间:1534492600637
运行结果显示也没有问题,记录了一个游戏的主要流程;心理学家告诉我们,人类对于苦难的记忆比对于喜悦的记忆要深刻,但是人类对于喜悦是“趋利”性的,每个人能都想Happy,都不想苦难靠近,要想获取幸福,苦难也在所难免的,游戏也是如此,打游戏时间长了,腰酸背痛,眼睛干涩,手臂发麻,胡思乱想,从而导致走火入魔。那怎么办?想玩游戏,又不想碰触到游戏的苦难中,如何解决呢?有办法,现在游戏代理的公司特别多,把自己的账号交给代练人员,修改代码...
微信截图_20180817161154.png在类图中添加了一个GamePlayerProxy类来代表玩家代练,它也不能作弊,也得动手打怪升级,所以同样需要实现IGamePlayer接口,代码如下:
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
//通过构造函数传递要对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer) {
this.gamePlayer = _gamePlayer;
}
//代练登录
@Override
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练打怪
@Override
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练升级
@Override
public void upgrade() {
this.gamePlayer.upgrade();
}
}
很简单,首先通过构造函数说明为谁代练打游戏,然后通过手动开始代理用户进行打怪升级,场景类Clint如下:
public class Client {
public static void main(String[] agrs) {
//定义一个游戏玩家
IGamePlayer player = new GamePlayer("test");
//定义一个代练者
IGamePlayer proxy = new GamePlayerProxy(player);
//开始打游戏。记录下时间戳
System.out.print("开始时间:"+System.currentTimeMillis()+"\n");
//登录
proxy.login("username" ,"password");
//开始打怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束时间
System.out.print("结束时间:"+System.currentTimeMillis());
}
}
运行结果如下,还是test玩家在打游戏:
开始时间:1534494690426
登录用户名:username的用户testsucces
test再打怪...
test又升级了...
结束时间:1534494690426
没有任何改变,但是游戏已经在升级了,有人帮你干活了,惹不起...
代理模式的定义
代理模式是一个使用率非常高的模式,定义如下:
Provide a surrogate or placeholder for another object to control access to it.(为另一个对象提供代理或占位符来控制对它的访问。)
代理模式也叫委托模式,它是一项基本设计技巧,许多其他模式,如状态模式、策略模式、访问模式本质上是在更特殊的场合采用了委托模式,而且在日常开发中,代理模式可以提供非常好的访问控制;
微信截图_20180817164723.png
代理模式通用类图角色定义:
- Subject抽象主题角色
抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求; - RealSubject具体主题颜色
也叫被委托角色,被代理角色,业务逻辑的具体执行者; - Proxy代理主题角色
也叫代理类、委托类,它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实的主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
Subject抽象主题类通用源码如下:
public interface Subject{
//定义一个方法
public void request();
}
在接口中定义了一个方法request来作为方法的代表,RealSubject对它进行实现,代码如下:
public class RealSubject implements Subject{
//实现方法
@Override
public void request() {
//业务逻辑处理
}
}
RealSubject是一个正常的业务实现类,代理模式的核心就在代理类上,代码如下
public class Proxy implements Subject{
//要代理哪个实现类
private Subject subject = null;
//默认被代理
public Proxy(){
this.subject = new Proxy();
}
//通过构造函数传递代理者
public Proxy(Object...objects){
}
//实现接口中定义的方法
@Override
public void request() {
this.after();
this.subject.request();
this.before();
}
//预处理
private void before(){
//do something
}
//善后处理
private void after(){
//do something
}
}
至于before和after方法,是一个引子崭新的模式。
一个代理类可以代理多个被委托者或者被代理者,因此一个代理者具体代理哪个真实的主题角色,是由场景类决定的。当然最简单的情况就是一个主题类和一个代理类,这就是最简单的代理模式。
代理模式的优点
-
职责清晰
真实的角色就是实现具体的业务逻辑,不用关心其他非本职的事务。 -
高扩展
具体主题角色是随时发生变化的,只要实现了接口,代理类可以不做任何修改使用; -
智能化
主要体现在动态代理上;ps:后边会分析强制代理...
网友评论