装饰模式
含义:为其他对象提供一种代理以控制对这个对象的访问。也可以说,一个类代表另一个类的功能
实现过程:
- 理论性:创建被代理类及代理类,客户端直接与代理类对象进行交互,间接实现了被代理类功能
- 比喻:上班狗没空肝游戏,需要找游戏代练,代练替我们肝了日常活动,即代替我们实现了打游戏这一操作
优缺点:
- 优点:
- 代码结构清晰
- 高扩展性(代理类既把被代理类实现,又可扩展自身功能)
- 智能化(动态代理)
- 缺点:
- 由于在客户端和真实主题(被代理对象)之间增加了代理对象,某些类型的代理模式可能会造成请求的处理速度变慢
- 介于两者中间的代理类,会造成额外的开销
适用场景:
- 远程代理:为了一个对象在不同的地址空间提供局部代表,进而隐藏对象存在于不同地址空间的事实
- 虚拟代理:根据需要创建开销很大的对象
- 安全代理:用于控制真实对象的访问权限
- 智能引用代理:指当调用真实的对象时,代理处理另外一些事
- 防火墙代理
- 同步化代理
- Cache代理
项目示例:
代理模式实现玩家找代练肝游戏的情景:
// 玩家与代练都会打游戏(公共接口): // ----------------------------- interface IPlayGame { void KillEnemy(); void KillBoss(); void MissionFinished(); } // 打的游戏(代理直接接触对象): // ------------------------- class Game { public Game(string name){ Name = name; } public string Name { get; set; } } // 玩家(被代理对象): // ----------------- class Player : IPlayGame { Game game; public Player(Game game) { this.game = game; } //玩家自己打游戏 public void KillEnemy(){ Console.WriteLine($"{game.Name} 击杀小兵!"); } public void KillBoss(){ Console.WriteLine($"{game.Name} 击杀Boss!"); } public void MissionFinished(){ Console.WriteLine($"{game.Name} 完成任务!"); } } // 代练(代理对象): // --------------- class PlayerProxy : IPlayGame { //代练替代玩家 Player player; public PlayerProxy(Game game) { player = new Player(game); } //代练打游戏 public void KillEnemy() { player.KillEnemy(); } public void KillBoss() { player.KillBoss(); } public void MissionFinished(){ player.MissionFinished(); } } class Client { static void Main(string[] args) { //创建打的游戏 Game LOL = new Game("英雄联盟代练:"); //创建代练、设定代练游戏 PlayerProxy playerProxy = new PlayerProxy(LOL); //代练代打 playerProxy.KillEnemy(); playerProxy.KillBoss(); playerProxy.MissionFinished(); /* OUT: 英雄联盟代练: 击杀小兵! 英雄联盟代练: 击杀Boss! 英雄联盟代练: 完成任务! */ } }