设计模式系列漫谈之九 - 代理模式
继续小雪的故事···
故事
小雪现就职于一家专门销售夏装的服装公司,小雪负责美国市场的销售业务。在过去的几个月里,由于公司的产品销售异常火爆,小雪不得不每天都奔跑在中国和美国两地。有时候,今天还在中国,一觉醒来就到了美国纽约。GPRS手机确实给小雪带来免去了不少烦恼,因为每到一个新的地方,手机就会自动给这些痴情的追求者问好,并告知所在位置。
众所周知,很多商品都有销售淡季,家纺夏天是淡季,啤酒冬天是淡季,蚊香冬春是淡季,空调春秋是淡季,夏装冬天是淡季,冬装夏天是淡季。近来,美国的气温开始下降。公司的产品销售量慢慢减少。小雪已经很长时间没有出差了。
突然有一天,有几个追求者打来电话问:“小雪,这段时间忙什么呢,这么长时间都没来短信。” 接下来的几天里,小雪接到了很多类似的电话。原来,小雪一直在公司上班,手机已经很长时间没有给他们发信息了。小雪想,我长时间不出差,是否一个功能代我每5个小时自动发出预先设置的默认短信呢?
代理模式(Proxy)的解决方案
GOF在《设计模式》中如此描述:为对象提供一种代理,以控制对对象的访问。代理模式需要定义三个角色:抽象对象、真实对象、代理对象。
以下是在本系列观察者模式基础上通过代理模式实现。请参见:设计模式系列漫谈之一 - 观察者模式
抽象对象如下:
代理对象如下:
被观察者对象如下:
GPRS手机一旦监测所在位置发生变化,立即调用OnAddressChanaged方法发送信息
mobile.OnAddressChanaged("小雪在纽约向你问好!");
故事
小雪现就职于一家专门销售夏装的服装公司,小雪负责美国市场的销售业务。在过去的几个月里,由于公司的产品销售异常火爆,小雪不得不每天都奔跑在中国和美国两地。有时候,今天还在中国,一觉醒来就到了美国纽约。GPRS手机确实给小雪带来免去了不少烦恼,因为每到一个新的地方,手机就会自动给这些痴情的追求者问好,并告知所在位置。
众所周知,很多商品都有销售淡季,家纺夏天是淡季,啤酒冬天是淡季,蚊香冬春是淡季,空调春秋是淡季,夏装冬天是淡季,冬装夏天是淡季。近来,美国的气温开始下降。公司的产品销售量慢慢减少。小雪已经很长时间没有出差了。
突然有一天,有几个追求者打来电话问:“小雪,这段时间忙什么呢,这么长时间都没来短信。” 接下来的几天里,小雪接到了很多类似的电话。原来,小雪一直在公司上班,手机已经很长时间没有给他们发信息了。小雪想,我长时间不出差,是否一个功能代我每5个小时自动发出预先设置的默认短信呢?
代理模式(Proxy)的解决方案
GOF在《设计模式》中如此描述:为对象提供一种代理,以控制对对象的访问。代理模式需要定义三个角色:抽象对象、真实对象、代理对象。
以下是在本系列观察者模式基础上通过代理模式实现。请参见:设计模式系列漫谈之一 - 观察者模式
抽象对象如下:
namespace XiaoXue
{
public abstract clas Boy
{
public bool Moved=false;
public string Address;
public virtual void ShowAddress()
{
Console.WriteLine(this.Address);
}
}
}
真实对象如下:
{
public abstract clas Boy
{
public bool Moved=false;
public string Address;
public virtual void ShowAddress()
{
Console.WriteLine(this.Address);
}
}
}
namespace XiaoXue
{
public class BoyA : Boy
{
public override void ShowAddress()
{
boy.ShowAddress();
}
}
public class BoyB : Boy
{
public override void ShowAddress()
{
boy.ShowAddress();
}
}
}
{
public class BoyA : Boy
{
public override void ShowAddress()
{
boy.ShowAddress();
}
}
public class BoyB : Boy
{
public override void ShowAddress()
{
boy.ShowAddress();
}
}
}
代理对象如下:
namespace XiaoXue
{
public class ProxyBoyA : Boy
{
private BoyA boy=null;
public ProxyBoyA(IBoy b)
{
boy=b;
}
public override void ShowAddress()
{
if (boy.Moved)
{
boy.ShowAddress();
}
else
{
base.ShowAddress();
}
}
}
public class ProxyBoyB : Boy
{
private BoyB boy=null;
public ProxyBoyB(IBoy b)
{
boy=b;
}
public override void ShowAddress()
{
if (boy.Moved)
{
boy.ShowAddress();
}
else
{
base.ShowAddress();
}
}
}
}
{
public class ProxyBoyA : Boy
{
private BoyA boy=null;
public ProxyBoyA(IBoy b)
{
boy=b;
}
public override void ShowAddress()
{
if (boy.Moved)
{
boy.ShowAddress();
}
else
{
base.ShowAddress();
}
}
}
public class ProxyBoyB : Boy
{
private BoyB boy=null;
public ProxyBoyB(IBoy b)
{
boy=b;
}
public override void ShowAddress()
{
if (boy.Moved)
{
boy.ShowAddress();
}
else
{
base.ShowAddress();
}
}
}
}
被观察者对象如下:
namespace XiaoXue
{
public class GPRSMobile
{
private ArrayList boys = new ArrayList(); //观察者列表
private string _DefaultAddress;
public GPRSMobile(string defaultAddress)
{
this._DefaultAddress=defaultAddress;
timer=new System.Timers..Timer();
timer.Interval=5*60*60*1000;
timer.Enabled=true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Notify(this._DefaultAddress,false);
}
public void AddBoy(Boy b)
{
boys.Add(b);
}
//通知所有观察者
private void Notify(string address,bool moved)
{
for (int i = 0; i < boys.Count; i++)
{
Boy boy=(Boy)boys[i];
boy.Moved=moved;
boy.Address=address;
boy.ShowAddress();
}
}
//当位置发生变化时执行
public void OnAddressChanaged(string newAddress)
{
Notify(newAddress,true);
}
}
}
客户端调用如下:
{
public class GPRSMobile
{
private ArrayList boys = new ArrayList(); //观察者列表
private string _DefaultAddress;
public GPRSMobile(string defaultAddress)
{
this._DefaultAddress=defaultAddress;
timer=new System.Timers..Timer();
timer.Interval=5*60*60*1000;
timer.Enabled=true;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Notify(this._DefaultAddress,false);
}
public void AddBoy(Boy b)
{
boys.Add(b);
}
//通知所有观察者
private void Notify(string address,bool moved)
{
for (int i = 0; i < boys.Count; i++)
{
Boy boy=(Boy)boys[i];
boy.Moved=moved;
boy.Address=address;
boy.ShowAddress();
}
}
//当位置发生变化时执行
public void OnAddressChanaged(string newAddress)
{
Notify(newAddress,true);
}
}
}
BoyA boya=new BoyA();
BoyB boyb=new BoyB();
GPRSMobile mobile=new GRPSMobile("正在公司上班呢")
mobile.AddBoy(boya);
mobile.AddBoy(boyb);
BoyB boyb=new BoyB();
GPRSMobile mobile=new GRPSMobile("正在公司上班呢")
mobile.AddBoy(boya);
mobile.AddBoy(boyb);
GPRS手机一旦监测所在位置发生变化,立即调用OnAddressChanaged方法发送信息
mobile.OnAddressChanaged("小雪在纽约向你问好!");
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述