定义

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

代理模式也叫做委托模式,它是一项基本设计技巧。许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式,而且在日常的应用中,代理模式可以提供非常好的访问控制。

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

基本上可以理解为:代理类持有实际操作对象的引用,通过公开方法将这些引用的方法提供给其它类调用。

和其它模式的区别

  1. 和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理迷失不能改变所代理类的接口。
  2. 和装饰模式的区别:装饰模式为了增强功能,而代理模式是为了加以控制。

UML

优点

  1. 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰。
  2. 具体主题角色是随时都会发生变化的,只要它实现了接口,甭管它如何变化,都逃不脱如来佛的手掌(接口),那我们的代理类完全就可以在不做任何修改的情况下使用。

缺点

  1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
  2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

应用场景

远程代理

为一个对象在不同的地址空间提供局部代表。

虚代理

根据需要创建开销很大的对象。比如浏览网页时,图片可以使用代理先按宽高进行占位,下载好再进行显示。

保护代理

控制对原始对象的访问。保护代理用于对象应该有不同的访问权限的时候。

智能指针

取代了简单的指针,它在访问对象时执行一些附加操作。

它的典型用途包括:

  1. 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它。
  2. 当第一次引用一个持久对象时,将它装入内存。
  3. 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。

示例

游戏玩家(被代练对象)和游戏代练者(代理对象)的示例,其中如果游戏玩家升级则游戏代练则要进行收费。

C++

C#

  1 using System;
  2
  3 namespace DesignPattern
  4 {
  5     class Program
  6     {
  7         static void Main(string[] args)
  8         {
  9             //李雷自己打游戏
 10             GamePlayer liLei = new GamePlayer("李雷");
 11             liLei.Login();
 12             liLei.KillMonster();
 13             liLei.Upgrade();
 14
 15             Console.WriteLine();
 16
 17             //李雷花钱请游戏代练帮其升级
 18             Leveling leveling = new Leveling(liLei);
 19             leveling.Login();
 20             leveling.KillMonster();
 21             leveling.Upgrade();
 22
 23             Console.Read();
 24         }
 25     }
 26
 27     /// <summary>
 28     /// 游戏玩家接口.
 29     /// </summary>
 30     public interface IGamePlayer
 31     {
 32         /// <summary>
 33         /// 登录.
 34         /// </summary>
 35         void Login();
 36
 37         /// <summary>
 38         /// 打怪.
 39         /// </summary>
 40         void KillMonster();
 41
 42         /// <summary>
 43         /// 升级.
 44         /// </summary>
 45         void Upgrade();
 46     }
 47
 48     /// <summary>
 49     /// 玩家类.
 50     /// </summary>
 51     public class GamePlayer : IGamePlayer
 52     {
 53         private string _name;
 54
 55         public GamePlayer(string name)
 56         {
 57             _name = name;
 58         }
 59
 60         public void Login()
 61         {
 62             Console.WriteLine("玩家\"" + _name + "\"登录游戏。");
 63         }
 64
 65         public void KillMonster()
 66         {
 67             Console.WriteLine("玩家\"" + _name + "\"开始打怪。");
 68         }
 69
 70         public void Upgrade()
 71         {
 72             Console.WriteLine("玩家\"" + _name + "\"等级提升一级。");
 73         }
 74     }
 75
 76     /// <summary>
 77     /// 游戏代练类.
 78     /// </summary>
 79     public class Leveling : IGamePlayer
 80     {
 81         private GamePlayer _gamePlayer;
 82
 83         public Leveling(GamePlayer gamePlayer)
 84         {
 85             _gamePlayer = gamePlayer;
 86         }
 87
 88         public void Login()
 89         {
 90             _gamePlayer.Login();
 91         }
 92
 93         public void KillMonster()
 94         {
 95             _gamePlayer.KillMonster();
 96         }
 97
 98         public void Upgrade()
 99         {
100             _gamePlayer.Upgrade();
101
102             Console.WriteLine("游戏代练者收费。");
103         }
104     }
105 }

View Code

Java

Java的示例使用延迟代理和动态代理查询天气的例子。

  1 public class Main
  2 {
  3     public static void main(String[] args)
  4     {
  5         //不使用代理
  6         IWeather weather1 = new ChinaWeather();
  7         System.out.println(weather1.getWeatherByCity("上海"));
  8
  9         //延迟代理
 10         IWeather weather2 = new ChinaWeatherDelayProxy();
 11         System.out.println(weather2.getWeatherByCity("北京"));
 12
 13         //动态代理
 14         IWeather weather3 = new WeatherDynamicProxy(new InternationalWeather());
 15         System.out.println(weather3.getWeatherByCity("北京"));
 16     }
 17
 18     /**
 19      * 天气查询接口
 20      */
 21     public interface IWeather
 22     {
 23         /**
 24          * 获取指定城市的天气情况
 25          */
 26         String getWeatherByCity(String city);
 27
 28         /**
 29          * 请求查询
 30          */
 31         void request();
 32     }
 33
 34     /**
 35      * 使用中国的天气服务器查询天气情况,只能查询到中国的天气
 36      */
 37     public static class ChinaWeather implements IWeather
 38     {
 39         public ChinaWeather()
 40         {
 41             this.request();
 42         }
 43
 44         @Override
 45         public String getWeatherByCity(String city)
 46         {
 47             if(city.equals("北京"))
 48             {
 49                 return "晴 28度 PM2.5 20";
 50             }
 51             if(city.equals("上海"))
 52             {
 53                 return "晴 33度 PM2.5 10";
 54             }
 55             return "未知";
 56         }
 57
 58         @Override
 59         public void request()
 60         {
 61             System.out.println("请求中国的天气服务器,解析其格式得到信息");
 62         }
 63     }
 64
 65     /**
 66      * 使用国际的天气服务器查询天气情况,当然也可以查询到中国的天气了
 67      */
 68     public static class InternationalWeather implements IWeather
 69     {
 70         public InternationalWeather()
 71         {
 72             this.request();
 73         }
 74
 75         @Override
 76         public String getWeatherByCity(String city)
 77         {
 78             if(city.equals("北京"))
 79             {
 80                 return "晴 29度 PM2.5 500+";
 81             }
 82             if(city.equals("上海"))
 83             {
 84                 return "晴 32度 PM2.5 500+";
 85             }
 86             return "未知";
 87         }
 88
 89         @Override
 90         public void request()
 91         {
 92             System.out.println("请求国际的天气服务器,解析其格式得到信息");
 93         }
 94     }
 95
 96     /**
 97      * 延迟代理
 98      */
 99     public static class ChinaWeatherDelayProxy implements IWeather
100     {
101         private IWeather weather;
102
103         private IWeather getWeather()
104         {
105             if(weather == null)
106             {
107                 weather = new ChinaWeather();
108             }
109             return weather;
110         }
111
112         @Override
113         public String getWeatherByCity(String city)
114         {
115             return getWeather().getWeatherByCity(city);
116         }
117
118         @Override
119         public void request()
120         {
121             getWeather().request();
122         }
123     }
124
125     /**
126      * 动态代理
127      */
128     public static class WeatherDynamicProxy implements IWeather
129     {
130         private IWeather weather;
131
132         public WeatherDynamicProxy(IWeather weather)
133         {
134             this.weather = weather;
135         }
136
137         @Override
138         public String getWeatherByCity(String city)
139         {
140             return weather.getWeatherByCity(city);
141         }
142
143         @Override
144         public void request()
145         {
146             weather.request();
147         }
148     }
149 }

View Code

AS3

我的经验总结

在PureMVC框架中,其Model层使用了Proxy的设计模式。

我们先看看Model层的主要功能:

  1. 保存程序数据;
  2. 远程消息发送及请求。

在我们的游戏中,分别存在UserData及SocketConnection这两个对象,其中UserData用来存储用户数据,SocketConnection用来处理所有远程消息的接收和发送,而每个模块的Proxy都是对这两个对象的代理,其提供该模块需要的数据和操作接口给该模块,比如技能模块中,Proxy会提供技能相关的数据和协议给到该模块的View层。代理类为模块提供了屏蔽不需要的接口的功能。

然而在PureMVC的升级版框架RobotLegs中,其定义的是MVCS的框架,Model层直接设计为Model+Services的组合,没有使用代理模式,由于没有代理模式,所以中介类中就不是直接操作代理类,而一般情况是通过发送Command,在Command中进行处理。

结构类模式(七):代理(Proxy)相关推荐

  1. 设计模式之结构类模式PK

    结构类模式包括: 适配器模式 桥梁模式 组合模式 装饰模式 门面模式 享元模式 代理模式 结构类模式着重于如何建立一个软件结构 为什么叫结构类模式呢? 因为他们都是通过组合类或对象产生更大结构以适应更 ...

  2. 设计模式中的结构类模式

    设计模式中的结构类模式 结构类模式包括适配器模式.桥梁模式.组合模式.装饰模式.门面模式.享元模式和代理模式. 适配器模式:修饰非血缘关系类,把一个非本家族的对象伪装成本家族的对象,因此它的本质还是非 ...

  3. [置顶]       设计模式之结构类模式——桥梁模式

    桥梁模式(Bridge Patter)也叫做桥接模式,是一个比较简单的模式. 定义: 将抽象和实现解耦,使得两者可以独立地变化. 通用类图: ● Abstraction--抽象化角色 它主要的职责是定 ...

  4. 设计模式之禅之结构类PK【装饰模式VS适配器模式】

    设计模式之禅PK之结构类 结构类设计模式 结构类模式: 适配器模式 桥梁模式 组合模式 装饰模式 门面模式 享元模式 代理模式 相同点:他们都是通过组合类或对象产生更大的结构以适应更高的层次的逻辑需求 ...

  5. 步步为营 .NET 设计模式学习笔记 七、Proxy(代理模式)

    概述 在软件系统中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来 ...

  6. 设计模式---代理(Proxy)模式

    1 定义 代理模式,为想要访问的对象创建一个代理,使访问原对象变为访问代理对象.代理模式可以提供非常好的访问控制.生活中最多的代理模式例子就是中介. 2 代理模式结构与实现 代理模式通用类图如下所示( ...

  7. Java 代理(proxy)模式

    代理模式(Proxy Pattern) 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...

  8. 【设计模式】代理模式 ( 动态代理 | 模拟 Java 虚拟机生成对应的 代理对象 类 )

    文章目录 前言 一.模拟 JVM 生成对应的 代理对象 二.模拟 JVM 生成对应的 代理对象 完整流程展示 1.目标对象接口 2.被代理对象 3.调用处理程序 4.模拟 JVM 生成的代理对象类 5 ...

  9. 设计模式学习笔记——代理(Proxy)模式

    设计模式学习笔记--代理(Proxy)模式 @(设计模式)[设计模式, 代理模式, proxy] 设计模式学习笔记代理Proxy模式 基本介绍 代理案例 类图 实现代码 Printable接口 Pri ...

  10. Proxy 代理模式 动态代理 CGLIB

    代理的基本概念 几个英文单词: proxy [ˈprɒksi] n. 代理服务器:代表权:代理人,代替物:委托书: invoke [ɪnˈvəʊk] vt. 乞灵,祈求:提出或授引-以支持或证明:召鬼 ...

最新文章

  1. python opencv创建图像_使用Python中OpenCV库创建一幅图片的RGB通道图片
  2. ASP.NET Core 1.0 使用 MySQL for EF Core 1.0 (.NET Core 1.0)
  3. mysql压力测试教程_Mysqlslap MySQL压力测试工具 简单教程
  4. 16第一章 ASP.Net编程基础知识
  5. hdu 2196(经典树形dp)
  6. Day-4: Python函数
  7. linux so_nosigpipe,TCP_NODELAY/SO_LINGER/SO_NOSIGPIPE/MSG_NOSIGNAL设置
  8. WPF实现截屏(仿微信)
  9. TWaver HTML5 + Node.js + express + socket.io + redis(五)
  10. Linux select 机制深入分析
  11. (转)C++的tie()函数
  12. python银行管理系统框架_基于Python的网上银行综合管理系统的设计与实现
  13. [5-20]绿色精品软件每天更新[uc23整理]
  14. 使用Node.js爬取双色球十六年来所有中奖号码
  15. visio流程图的叉号_【转】Visio绘制WEB流程图的心得
  16. OSPF--DR与BDR
  17. 一个可以提升180%推广效果的信息流广告投放策略
  18. 数学建模美国赛论文常用句式总结
  19. Apache POI简介
  20. AD20的最全安装步骤

热门文章

  1. jQuery.ajax(解决跨域问题,jquery解决AJAX跨域问题
  2. angularjs java 实例_[Java教程]angularjs小练习(分别通过ng
  3. mysql从库新增_MySQL新增从库
  4. java读取excel的常用办法
  5. 项目实战-1读取记事本中的文件,写入到slice切片中。
  6. java--idea--生成jar包-2
  7. 梳理的关于mongodb的基础使用命令:----查询记录点--推荐使用:
  8. poythoncode-实战4--读取文本文件,csv文件,存到系统中以大列表方式进行存储
  9. SQL分组字符串相连
  10. firmware linux 原理_Firmware加载原理分析 | 学步园