设计模式-结构型-代理模式
为其他对象提供一个代理对象,以控制被代理对象的访问,例如原告和被告不需要懂法律细节,有代理律师代为处理,实际结果有原告和被告执行。
前言
例如:原告和被告不需要懂法律细节,有代理律师代为处理,实际结果由原告和被告执行。
一、代理模式
在某些情况下,一个对象不能直接引用另一个对象,而代理对象可以起到呈上启下的作用,为其他对象提供一个代理对象,以控制被代理对象的访问。
- 目的:
- 保护被代理对象,
- 增强目标对象
二、应用场景
- 租房中介:中介代理房东,租客直接找中介就可以租到房子
- 婚姻介绍:中介手中有男女信息,中介代为匹配介绍
- 经纪人:帮助处理日常事务
三、角色
以租房中介看角色
- 抽象主题角色 (ISubject):声明代理类要代理的RealSubject的方法,可以是接口或抽象类。【出租房屋操作】
- 真实主题角色 (RealSubject:被代理类):负责执行真正的业务逻辑。【房东类–(出租房屋)】
- 代理主题角色 (Proxy:代理类):内部引用了RealSubject,具有RealSubject的代理权力,可以在进入被代理类方法前后,执行一系列操作,调用者无感。【中介类—代理出租房屋操作】
四、静态代理实现
1.抽象主题角色
代码如下(示例):定义需要代理来执行的方法
/// <summary>
/// 抽象代理方法
/// </summary>
public interface IHouseProxy
{
public void DoLease(string name);
}
2.真实主题角色
代码如下(示例):抽象代理方法的真实实现
/// <summary>
/// 真实主题《房东》
/// </summary>
public class House : IHouseProxy
{
public void DoLease(string name)
{
Console.WriteLine($"我是房东:{name}租了房子");
}
}
3.代理主题角色
代码如下(示例):代理类
/// <summary>
/// 房子代理《中介》
/// </summary>
public class HouseProxy : IHouseProxy
{
private House house;
public HouseProxy(House house)
{
this.house = house;
}
public void DoLease(string name)
{
Console.WriteLine($"我只是中介,{name}租了个房子");
this.house.DoLease(name);
Console.WriteLine($"我是中介,{name}租房子成功");
}
}
4.访问代理类
代码如下(示例):客户端类通过操作代理类,实现被代理类的操作。
/// <summary>
/// 调用客户端《租客》
/// </summary>
public class ProxyClient
{
public void ClientOne()
{
var proxy = new HouseProxy(new House());
Console.WriteLine("我是租客张三,我要租房子");
proxy.DoLease("张三");
}
}
5.运行结果
代码如下(示例):客户端类通过操作代理类,实现被代理类的操作。
结构型设计模式
我是租客张三,我要租房子
我只是中介,张三租了个房子
我是房东:张三租了房子
我是中介,张三租房子成功
五、代理模式扩展
- 静态代理:通过手动完成代理操作,如果被代理类增加新方法,代理类需要同步增加,违背了开闭原则。
- 动态代理:在运行时动态生成代码的方式,取消了被代理类的扩展限制,遵循了开闭原则。(推荐)
总结
- 优点
将代理对象与真实被调用目标对象分离,
在一定程度上降低了系统的耦合性,扩展性好,
保护目标对象,
增强目标对象, - 缺点
会造成系统设计中类的数量增加,
在客户端和目标对象中增加一个代理对象,导致处理请求的速度变慢,
增加了系统的复杂度。