设计模式系列漫谈之九 - 代理模式
继续小雪的故事···
故事
小雪现就职于一家专门销售夏装的服装公司,小雪负责美国市场的销售业务。在过去的几个月里,由于公司的产品销售异常火爆,小雪不得不每天都奔跑在中国和美国两地。有时候,今天还在中国,一觉醒来就到了美国纽约。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("小雪在纽约向你问好!");