本文主要参考资料:《设计模式之禅》
代理模式又叫委托模式,是很重要的模式,所以我们将以三篇文章来讲解,本文主要以一个例子来浅显的介绍下代理模式
本文主要目录为:
1)案例
2)代理模式改进案例
3)代理模式的定义
1. 案例
大家应该都玩过游戏吧,杀怪升级什么之类的。我们现在把打游戏过程系统化,下面是类图与代码:
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;
}
//打怪,最期望的就是杀老怪
public void killBoss() {
System.out.println(this.name + "在打怪!");
}
//进游戏之前你肯定要登录吧,这是一个必要条件
public void login(String user, String password) {
System.out.println("登录名为"+user + " 的用户 " + this.name + "登录成功!");
}
//升级,升级有很多方法,花钱买是一种,做任务也是一种
public void upgrade() {
System.out.println(this.name + " 又升了一级!");
}
}
public class Client {
public static void main(String[] args) {
//定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("张三");
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
player.login("zhangSan", "password");
//开始杀怪
player.killBoss();
//升级
player.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
2. 代理模式改进案例
但有时候,我们并不想花太多时间玩游戏,但又想升级能升得快,怎么办?招人代练啊!我们抱我们的账号交给代练人员,由他们去帮我们升级打怪,所以我们将类图改为下面:
在上面的代码基础上再添加下面代码
public class GamePlayerProxy implements IGamePlayer {
private IGamePlayer gamePlayer = null;
//通过构造函数传递要对谁进行代练
public GamePlayerProxy(IGamePlayer _gamePlayer){
this.gamePlayer = _gamePlayer;
}
//代练杀怪
public void killBoss() {
this.gamePlayer.killBoss();
}
//代练登录
public void login(String user, String password) {
this.gamePlayer.login(user, password);
}
//代练升级
public void upgrade() {
this.gamePlayer.upgrade();
}
}
public class Client {
public static void main(String[] args) {
//定义一个痴迷的玩家
IGamePlayer player = new GamePlayer("张三");
//然后再定义一个代练者
IGamePlayer proxy = new GamePlayerProxy(player);
//开始打游戏,记下时间戳
System.out.println("开始时间是:2009-8-25 10:45");
proxy.login("zhangSan", "password");
//开始杀怪
proxy.killBoss();
//升级
proxy.upgrade();
//记录结束游戏时间
System.out.println("结束时间是:2009-8-26 03:40");
}
}
3. 代理模式的定义
定义:provide a surrogate or placeholder for another object to control access to it.为其他对象提供一种代理以控制对这个对象的访问。
代理模式的类图如下:
代理模式也叫做委托模式,它是一项基本设计技巧,许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了代理模式,而且在日常的应用中,代理模式可以提供非常好的访问控制,在一些著名开源软件中也经常见到它的身影,如Struts2的Form元素映射就采用了代理模式(准确的说是动态代理模式)。我们先看一下类图中的三个角色的定义:
- Subject抽象主题角色。抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。
- RealSubject 具体主题角色。也叫做被委托角色、被代理角色,它才是冤大头,是业务逻辑的具体执行者。
- Proxy代理主题角色。也叫做委托类、代理类,它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。
代码模板为:
public interface Subject {
//定义一个方法
public void request();
}
public class RealSubject implements Subject {
//实现方法
public void request() {
//业务逻辑处理
}
}
public class Proxy implements Subject {
//要代理哪个实现类
private Subject subject = null;
//默认被代理者
public Proxy(){
this.subject = new Proxy();
}
public Proxy(Subject _subject){
this.subject = _subject;
}
//通过构造函数传递代理者
public Proxy(Object...objects ){
}
//实现接口中定义的方法
public void request() {
this.before();
this.subject.request();
this.after();
}
//预处理
private void before(){
//do something
}
//善后处理
private void after(){
//do something
}
}
public class Client {
public static void main(String[] args) {
Subject realSub = new RealSubject();
Subject proxy = new Proxy(realSub);
proxy.request();
}
}