这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
代理模式:为其他对象提供一种代理以控制对这个对象的访问。
其通用设计图如下图所示:精髓是RealSubject类和Proxy类都实现Subject,使用Proxy类来限制对RealSubject类的访问
Subject抽象主题类: 抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求
RealSubject具体角色:也叫做被委托角色,被代理角色。是业务逻辑的具体执行者。
Proxy代理主题角色:也叫做委托类,代理类。它负责对真实角色的应用,将抽象类中定义的方法委托给真实角色实现,自己执行。
职责清晰:真实角色就是实现实际的业务逻辑,不用关心其他非本职的事物。
高扩展性:真实角色可以随时更换或扩展,只需要实现接口就行,而代理不需要有任何变化
借用大话设计模式中的例子,董卓让卢布帮忙追貂蝉(貂蝉不认识董卓),第一次让卢布送了一个娃娃,第二次让吕布送了一个花,第三次让吕布送了一件巧克力,貂蝉对吕布说:布,我们在一起吧。吕布说,这些东西是董卓让我送你的呀,貂蝉说:那又有什么关系呢,我喜欢的是你呀~他们两个就愉快地在一起了。
故事很狗血,但是董卓让吕布给貂蝉送礼物,就是一种代理。至于代理的结果,在代码中我们是可控的,人就不好说了。
不废话了,这个例子是用代理模式怎么实现呢?
1:代理接口ISeeker.cs
namespace Proxy
{
/// <summary>
/// 送礼物接口
/// </summary>
public interface ISeeker
{
void GiveDolls();
void GiveFlowers();
void GiveChocolate();
}
}
2:追求者类 Suitor.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proxy
{
/// <summary>
/// 追求者类
/// </summary>
public class Suitor:ISeeker
{
/// <summary>
/// 定义一个被追求者的对象
/// </summary>
public Girl mm;
/// <summary>
/// 构造函数(传入被追求者类,这里主要用来获取被追求者的名字,或者直接传被追求者的名字也可以)
/// </summary>
/// <param name="mm"></param>
public Suitor(Girl mm)
{
this.mm = mm;
}
/// <summary>
/// 送娃娃
/// </summary>
public void GiveDolls()
{
Console.WriteLine(mm.name + ",送你的娃娃");
}
/// <summary>
/// 送花
/// </summary>
public void GiveFlowers()
{
Console.WriteLine(mm.name + ",送你的花");
}
/// <summary>
/// 送巧克力
/// </summary>
public void GiveChocolate()
{
Console.WriteLine(mm.name + ",送你的巧克力");
}
}
}
3:代理类:proxy.cs 实现送礼物接口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proxy
{
/// <summary>
/// 代理类:同样实现送礼物接口
/// </summary>
public class proxy:ISeeker
{
/// <summary>
/// 定义一个追求者对象(精髓)
/// </summary>
public ISeeker lvbu;
/// <summary>
/// 构造函数(实例化一个追求者对象,但是这个对象用来代理追求者追姑娘)
/// </summary>
/// <param name="mm"></param>
public proxy(Girl mm)
{
lvbu = new Suitor(mm);
}
public void GiveDolls()
{
lvbu.GiveDolls();
}
public void GiveFlowers()
{
lvbu.GiveFlowers();
}
public void GiveChocolate()
{
lvbu.GiveChocolate();
}
}
}
4:被追求者类:Gril.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proxy
{
/// <summary>
/// 被追求者类
/// </summary>
public class Girl
{
public string name;
public Girl(string name)
{
this.name = name;
}
}
}
5:高层模块调用 program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Proxy
{
class Program
{
static void Main(string[] args)
{
// 实例化一个被追求者
Girl mm = new Girl("饭饭");
// 实例化一个代理对象
proxy lvbu = new proxy(mm);
// 代理对象送姑娘礼物
lvbu.GiveDolls();
lvbu.GiveFlowers();
lvbu.GiveChocolate();
Console.ReadKey();
}
}
}
实现效果如下图所示:
以上我们就实现了简单的代理模式。
代理模式分两种,动态代理和静态代理。
我们上边实现的是静态代理,代理类是我们自己定义的。
动态代理,代理类的代码是动态生成的,这个相对来说难度要高一些,以后遇到再看。
静态代理总结:
优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展。
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。
有好的建议,请在下方输入你的评论。 欢迎访问个人博客 guanchao.site
欢迎访问小程序: