代理模式(Proxy Pattern)。

定义:

为其他对象一种代理以控制对这个对象的访问。

代理模式也叫作委托模式,它是一项基本设计技巧,许多其他模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式,而且在日常的应用中,代理模式提供非常好的访问控制。在一些著名的开元然间中也经常见到他的身影,如Struts2的Form元素映射就采用了代理模式(准确的说是动态代理模式)。

通用代码:

抽象主题类

抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

public interface Subject {

// 定义一个方法

public void request();

}

真实主题类

也叫作被委托角色,被代理角色,是业务逻辑的具体执行者。

publc class RealSubject implements Subject {

// 实现方法

public void request() {

// 业务逻辑处理

}

}

代理类

也叫作委托类、代理类。它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

public class Proxy implements Subject {

// 要代理哪个实现类

private Subject subject = null;

// 默认被代理类

public Proxy() {

this.subject = new Proxy();

}

// 通过构造函数传递代理者

public Proxy(Object... objects) {}

// 实现接口中定义的方法

public void request() {

this.before();

this.subject.request();

this.after();

}

//  预处理

public void before() {

// do Something

}

// 善后处理

public void after() {

// do Something

}

}

一个代理类可以代理多个被委托者或被代理者,因此一个代理类具体代理哪个真实主题角色,是由场景类决定的。当然,最简单的情况就是一个主题类和一个代理类,这是最简单的代理模式。在通常情况下,一个接口只需要一个代理类就可以了,具体代理哪个实现类由高层模块来决定,也就是在代理的构造函数中传递被代理类,你要代理谁就产生该代理的实例,然后把被代理者传递进来,该模式在实际的项目应用中使用比较广泛。

优点:

  • 职责清晰

真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编码简洁清晰。

  • 高扩展性

具体主题角色是随时都会发生变化的,只要它实现了接口,甭管他如何变化,都逃不脱如来佛的手掌(接口),那我们的代理完全就可以在不做任何修改的情况下使用。

  • 智能化

例如Struts是如何把表单元素映射到对象上的。

使用场景:

代理模式的使用场景非常多,大家可以看看Spring AOP,这是一个非常典型的动态代理。

扩展:

1、普通代理

普通代理是我们要知道代理的存在,然后才能访问;

2、强制代理

强制代理是调用者直接调用真是角色,而不用关心代理是否存在,其代理的产生是由真是角色决定的。

3、代理是有个性的

4、动态代理

最佳实践:

代理模式应用的非常广泛,大到一个系统框架、企业平台,小到代码片段、事务处理,稍不留意就用到代理模式。可能该模式是大家接触最多的模式,而且有了AOP大家写代理就更加简单了,有类似Spring AOP和AspectJ这样非常优秀的工具,拿来主义即可!不过大家可以看看源代码,特别是调试时,只要看到类似$Proxy()这样的结构,你应该知道这是一个动态代理了。

代码案例:

游戏者接口

public interface IGamePlayer {

// 登录游戏

public void login(String user,String password);

// 杀怪,网络游戏的主要特色

public void killBoss();

// 升级

public void upgrade();

}

游戏者

public GamePlayer implements IGamePlayer {

private String name ="";

// 通过构造函数传递名称

public GamePlayer(String _name) {

this.name = _name;

}

// 打怪,最期望的就是杀boss

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 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 class Client {

public static void main(String[] args) {

// 定义一个痴迷的玩家

IGamePlayer player = new GamePlayer("张三");

// 然后再定义一个代练者

IGamePlayer proxy = new GamePlayerProxy(player);

// 开始打游戏,记下时间戳

System.out.println("开始时间是:2017-01-01 23:27");

proxy.login("zhangSan","password");

// 开始杀怪

proxy.killBoss();

// 升级

proxy.upgrade();

// 记录结束游戏时间

System.out.println("结束时间是:2017-01-02 01:30");

}

}

普通代理的游戏者

public class GamePlayer implements IGamePlayer {

  private String name ="";

  // 构造函数限制谁能创建对象

  public GamePlayer(IGamePlayer _gamePlayer, String _name) throws Exception {

    if(_gamePlayer == null) {

throws new Exception("不能创建真实角色!");

    } else {

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 GamePlayerProxy implements IGamePlayer {

private IGamePlayer gamePlayer = null;

// 通过构造函数传递要对谁进行代练

public GamePlayerProxy(String name) {

try{

gamePlayer = new GamePlayer(this.name);

} catch (Exception e) {

// TDO 异常处理

}

}


// 打怪,最期望的就是杀老怪

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 proxy = new GamePlayerProxy("张三");

// 开始打游戏,记下时间戳

System.out.println("开始时间是:2017-01-01 23:27");

proxy.login("zhangSan","password");

// 开始杀怪

proxy.killBoss();

// 升级

proxy.upgrade();

// 记录结束游戏时间

System.out.println("结束时间是:2017-01-02 01:30");


}

}

// 强制代理的接口类

public interface IGamePlayer {

// 登录游戏

public void login(String user , String password);

// 杀怪,这是网络游戏的 主要特色

public void killBoss();

//升级

public void upgrade();

// 每个人都可以找一下自己的代理

public IGamePlayer getProxy();

}

// 强制代理的真实角色

public class GamePlayer Implements IGamePlayer {

private String name = "";

// 我的代理是谁

private IGamePlayer proxy = null;

public GamePlayer(String _name) {

this.name = _name;

}

// 找到自己的代理

public IGamePlayer getProxy() {

this.proxy = new GamePlayerProxy(this);

return this.proxy;

}

// 打怪,最期望的是杀老怪

public void killBoss() {

if(this.isProxy()) {

System.out.println(this.name + "在打怪!");

} else {

System.out.println("请使用指定的代理访问");

}

}

// 进游戏之前你肯定要登录游戏吧,这是一个必要条件

public void login(String user , String password) {

if(this.isProxy()) {

System.out.println("登陆名为" + user + "的用户" + this.name + "登录成功!");

} else {

System.out.println("请使用指定的代理访问");

}

}

// 升级,升级有很多方法,花钱买是一种,做任务也是一种

public void upgrade(){

if(this.isProxy()) {

System.out.println(this.name + " 又升了一级!");

} else {

System.out.println("请使用指定的代理访问");

}

}

// 校验是否是代理访问

private boolean isProxy() {

if(this.proxy == null) {

return false;

} else {

return true;

}

}

}


// 强制代理的代理者

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 IgamePlayer getProxy() {

return this;

}


}

// 强制代理的场景类

public class Client {

public static void main(String[] args) {

// 定义一个游戏的角色

IGamePlayer player = new GamePlayer("张三");

// 获得指定的代理

IGamePlayer proxy = player.getProxy();

// 开始打游戏,记下时间戳

System.out.println("开始时间是:2017-01-01 23:27");

proxy.login("zhangSan","password");

// 开始杀怪

proxy.killBoss();

// 升级

proxy.upgrade();

// 记录结束游戏时间

System.out.println("结束时间是:2017-01-02 01:30");


}

}

// 代理是有个性的

代理类的接口

public interface IProxy {

// 计算费用

public void count();

}

// 代理类


public class GamePlayerProxy implements IGamePlayer, IProxy {

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();

this.count();

} 

// 计算费用

public void count() {

System.out.println("升级总费用是:150元");

}

}

 

以下是组合模式、装饰器模式、外观模式、享元模式和代理模式的应用案例和代码实现步骤的简要说明: 1. 组合模式 (Composite Pattern): 应用案例:文件系统的目录结构可以使用组合模式来表示,其中目录和文件都可以作为容器或叶子节点,可以方便地进行递归操作。 代码实现步骤:创建一个抽象类或接口表示组件,其中包含添加、删除和获取子组件的方法。实现类分别表示叶子节点和容器节点,容器节点可以包含其他组件。 2. 装饰器模式 (Decorator Pattern): 应用案例:在一个图形绘制软件中,可以使用装饰器模式来实现不同的图形对象以及对图形进行装饰,例如添加颜色、添加边框等。 代码实现步骤:创建一个抽象类或接口表示基本对象或装饰器,其中包含一个基本对象的引用。具体装饰器类继承自该抽象类,并在调用方法时添加额外的功能。 3. 外观模式 (Facade Pattern): 应用案例:在一个电子商务平台中,可以使用外观模式来创建一个统一的接口,将不同子系统的功能封装起来,便于客户端调用。 代码实现步骤:创建一个外观类,该类提供了一个简单的接口来调用多个子系统的功能,并在内部进行协调和管理。 4. 享元模式 (Flyweight Pattern): 应用案例:在一个游戏中,可以使用享元模式来共享不同的游戏资源对象,例如共享相同的纹理、音频等,以减少内存的使用。 代码实现步骤:创建一个享元工厂类来管理共享对象,通过池化技术来缓存和重用对象,并提供一个获取共享对象的方法。 5. 代理模式 (Proxy Pattern): 应用案例:在一个网络请求中,可以使用代理模式来代表真实的网络请求对象,以进行一些额外的操作,例如鉴权、缓存等。 代码实现步骤:创建一个接口或抽象类来表示真实对象和代理对象,代理对象持有一个真实对象的引用,并在调用方法时进行一些额外的处理。 以上是这些设计模式的简要应用案例和代码实现步骤。在实际开发中,可以根据具体需求选择合适的设计模式,并根据设计模式的原则进行设计和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值