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

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

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

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

和其它模式的区别

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

UML

结构类模式(七):代理(Proxy)

优点

  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

相关文章: