前置文章: 用心理解设计模式——设计模式的原则
设计模式相关代码已统一放至 我的 Github
一、定义
结构型模式之一。
Provide a surrogate or placeholder for another object to control acess to ot.
(为其他对象提供一种代理,以控制对这个对象的访问)
二、结构解析
代理模式的一般结构有三种角色:抽象主题、真实主题(被代理者)、代理者。
抽象主题,负责定义和声明真实主题要被代理的业务方法接口。
真实主题,继承抽象主题,实现自己真实的业务方法接口。
代理者,也继承抽象主题,拥有与真实主题(被代理者)相同的要被代理的业务方法接口, 从外观上看代理者与被代理者似乎一样。代理者内部依赖真实主题,实现这些业务方法接口时,最终调用了真实主题(被代理者)的业务方法,但可以在预先或之后进行了一些额外的处理。
三、评价
代理模式封装了客户访问或控制真实主题(被代理者)的过程,充当代理作用,解除了客户和真实主题之间的直接耦合。
各自职责变得清晰,符合开闭原则, 非常易扩展。
在真实主题不唯一, 但代理过程相同时,只需新增真实主题类即可(对扩展开放),而不用修改已有的代理类和已有的真实主题类(对修改关闭)。
在真实主题唯一, 但代理过程不同时,只需新增满足需求的代理类(对扩展开放),而不用修改已有的代理类和已有的真实主题类(对修改关闭)。
在真实主题唯一, 代理过程也不同时,可以同时扩展且不用修改已有的代理类和已有的真实主题类。
四、实现
namespace Proxy
{
//抽象主题
public abstract class Subject
{
//定义和声明真实主题要被代理的业务方法接口
public abstract void DoSth();
}
//真实主题
public class RealSubject : Subject
{
//实现业务方法接口,真实要做的事情。
public override void DoSth(){}
}
//代理者
public class Proxy : Subject
{
//内部依赖真实主题
private Subject subject = new RealSubject();
//代理者拥有与真实主题(被代理者)
public override void DoSth()
{
//额外的预先操作
this.Before();
//最终调用真实主题的业务方法
this.subject.DoSth();
//额外的后续操作
this.After();
}
private void Before() { }
private void After() { }
}
public class Client
{
static public void Main()
{
Proxy proxy = new Proxy();
proxy.DoSth();
}
}
}
五、真实主题和代理过程扩展
namespace Proxy.ExpandBoth
{
public abstract class Subject
{
public abstract void DoSth();
}
//真实主题A
public class RealSubjectA : Subject
{
public override void DoSth() { }
}
//真实主题B
public class RealSubjectB : Subject
{
public override void DoSth() { }
}
//代理X
public class ProxyX : Subject
{
//在构造代理者时确定代理哪个真实主题
private Subject subject = null;
public ProxyX(Subject subject)
{
this.subject = subject;
}
public override void DoSth()
{
this.BeforeX();
this.subject.DoSth();
this.AfterX();
}
private void BeforeX() { }
private void AfterX() { }
}
//代理Y
public class ProxyY : Subject
{
//在构造代理者时确定代理哪个真实主题
private Subject subject = null;
public ProxyY(Subject subject)
{
this.subject = subject;
}
public override void DoSth()
{
this.BeforeB();
this.subject.DoSth();
this.AfterB();
}
private void BeforeB() { }
private void AfterB() { }
}
public class Client
{
static public void Main()
{
RealSubjectA realSubjectA = new RealSubjectA();
RealSubjectB realSubjectB = new RealSubjectB();
//X代理真实主题A
ProxyX proxyXA = new ProxyX(realSubjectA);
proxyXA.DoSth();
//X代理真实主题B
ProxyX proxyXB = new ProxyX(realSubjectB);
proxyXB.DoSth();
//Y代理真实主题A
ProxyY proxyYA = new ProxyY(realSubjectA);
proxyYA.DoSth();
//Y代理真实主题B
ProxyY proxyYB = new ProxyY(realSubjectB);
proxyYB.DoSth();
}
}
}
六、动态代理
TODO