设计模式系列漫谈之九 - 代理模式

继续小雪的故事···

故事
       小雪现就职于一家专门销售夏装的服装公司,小雪负责美国市场的销售业务。在过去的几个月里,由于公司的产品销售异常火爆,小雪不得不每天都奔跑在中国和美国两地。有时候,今天还在中国,一觉醒来就到了美国纽约。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);
         }
    }
真实对象如下:
namespace XiaoXue
{
    
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();
               }
           }
    }
}

被观察者对象如下:
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);
        }
    }
}
客户端调用如下:
BoyA boya=new BoyA();
BoyB boyb
=new BoyB();

GPRSMobile mobile
=new GRPSMobile("正在公司上班呢")
mobile.AddBoy(boya);
mobile.AddBoy(boyb);

GPRS手机一旦监测所在位置发生变化,立即调用OnAddressChanaged方法发送信息
mobile.OnAddressChanaged("小雪在纽约向你问好!");
posted @ 2007-12-22 15:50  李华星  阅读(1637)  评论(0编辑  收藏  举报