设计模式(C#)——11代理模式
推荐阅读:
前言
在软件开发过程中,当无法直接访问某个对象或访问某个对象存在困难时,我们希望可以通过一个中介来间接访问,这就是今天我们要研究的代理模式。
介绍
代理模式:为其他对象提供一种代理以控制对这个对象的访问,一个类代表另一个类的功能。为了保证客户端使用的透明性,所访问的真实对象与代理对象需要实现相同的接口。
代理模式的元素:
(1) Subject(抽象主题):它声明了真实主题和代理主题的共同接口,这样一来在任何使用真实主题的地方都可以使用代理主题,客户端通常需要针对抽象主题角色进行编程。
(2) Proxy(代理主题):它包含了对真实主题的引用,从而可以在任何时候操作真实主题对象;在代理主题角色中提供一个与真实主题角色相同的接口,以便在任何时候都可以替代真实主题;代理主题角色还可以控制对真实主题的使用,负责在需要的时候创建和删除真实主题对象,并对真实主题对象的使用加以约束。通常,在代理主题角色中,客户端在调用所引用的真实主题操作之前或之后还需要执行其他操作,而不仅仅是单纯调用真实主题对象中的操作。
(3) RealSubject(真实主题):它定义了代理角色所代表的真实对象,在真实主题角色中实现了真实的业务操作,客户端可以通过代理主题角色间接调用真实主题角色中定义的操作。
下面举个例子来介绍下代理模式:
假设有一群人是互相的好朋友,其中A和B吵架了,A想和B和好,但是由于不好意思直接说,因此就随便找了剩下人中的一个(假设是C),想C帮A给B道歉。此时把除AB剩余的人作为抽象主题,把A作为代理主题,C就是真实主题。
1.创建抽象主题
abstract class Friends
{
public abstract void Apology(string msg);
protected virtual void Apologyed()
{
Console.WriteLine("帮忙道歉完成~~~~~");
}
}
2.真实主题
class Friend_C: Friends
{
public override void Apology(string msg)
{
//业务方法具体实现代码
Console.WriteLine(msg);
Apologyed();
}
protected override void Apologyed() {
Console.WriteLine("Friend_C帮忙道歉完成~~~~~");
}
}
3.代理类
class Friend_A: Friends
{
private Friend_C friend_C= new Friend_C(); //维持一个对真实主题对象的引用
public override void Apology(string msg)
{
friend_C.Apology(msg);
}
}
4.使用代理模式
public class Program {
private static Friend_A friend_A= null;
public static void Main(string[] args) {
friend_A= new Friend_A();
friend_A.Apology("对不起B,我(A)错了");
Console.ReadKey();
}
}
5.整合后的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 代理模式
{
abstract class Friends
{
public abstract void Apology(string msg);
protected virtual void Apologyed()
{
Console.WriteLine("帮忙道歉完成~~~~~");
}
}
class Friend_C : Friends
{
public override void Apology(string msg)
{
//业务方法具体实现代码
Console.WriteLine(msg);
Apologyed();
}
protected override void Apologyed() {
Console.WriteLine("Friend_C帮忙道歉完成~~~~~");
}
}
class Friend_A : Friends
{
private Friend_C friend_C = new Friend_C (); //维持一个对真实主题对象的引用
public override void Apology(string msg)
{
friend_C .Apology(msg);
}
}
public class Program
{
private static Friend_A friend_A= null;
public static void Main(string[] args)
{
friend_A= new Friend_A ();
friend_A.Apology("对不起B,我(A)错了");
Console.ReadKey();
}
}
}
优缺点
优点:
职责清晰;高扩展性;智能化。
缺点:
由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢;实现代理模式需要额外的工作,有些代理模式的实现非常复杂。
总结
在实际开发过程中,代理类的实现比上述代码要复杂很多,代理模式根据其目的和实现方式不同可分为很多种类,其中常用的几种代理模式简要说明如下:
(1) 远程代理(Remote Proxy):为一个位于不同的地址空间的对象提供一个本地的代理对象,这个不同的地址空间可以是在同一台主机中,也可是在另一台主机中,远程代理又称为大使(Ambassador)。
(2) 虚拟代理(Virtual Proxy):如果需要创建一个资源消耗较大的对象,先创建一个消耗相对较小的对象来表示,真实对象只在需要时才会被真正创建。
(3) 保护代理(Protect Proxy):控制对一个对象的访问,可以给不同的用户提供不同级别的使用权限。
(4) 缓冲代理(Cache Proxy):为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
(5) 智能引用代理(Smart Reference Proxy):当一个对象被引用时,提供一些额外的操作,例如将对象被调用的次数记录下来等。