设计模式系列漫谈之四 - 装饰模式

故事

      有一天,小雪的一个小学同学打电话告诉她,老同学马上要结婚了,婚礼将于2月14日举行。由于这个同学长期在外工作,很少联系,现在突然要结婚了,对此,小雪既羡慕又好奇。羡慕的是老同学脸上洋溢的微笑,好奇的是新郎究竟是何方人士。这时老同学给她发短信说,她的老公名叫林郇,在一家外企工作。小雪看到短信后郁闷半天,林郇? [郇]字怎么读啊?为了避免在婚礼上把名叫错,为了避免发生尴尬,小雪突然想起她的手机有语音读短信的功能。于是,她新建一条短信,用手写识别写了这个[郇]字,然后保存,然后打开语音识别选项,加载完成后,打开这条短信,于是,手机读出了这个字为[xun二声],嘿嘿。小雪又突发奇想,近段时间的短信太多了,一天要看好几十次,特别是在开车时读短信息太危险,何不把短信读出来呢?

      现在我们必须为小雪解决的问题是: 把追求者发送的短信的同时,能够转换为语音并且读出来(装饰行为)。直接修改各类型手机的具体类,很明显,这种做法不符合设计模式中的"开-闭"原则。

装饰模式(Decorator)的解决方案:
装饰模式的本质在于装饰,为现有的行为“装饰”额外的职责;
装饰模式的实现方式是通过一个抽象类继承被装饰的类或接口,同时聚合该类的实例对象。


短信接口如下:

namespace  XiaoXue
{
   
public   interface  IMessage
   {
        
void  SendMessage( object  Msg);
   }
}

短信具体类如下:

namespace  XiaoXue
{
    
public   class  NOKIA : IMessage
    {
        
public   void  SendMessage( object  msg)
        {
            
// 发送NOKIA短信;
        }
    }

    
public   class  MOTOROLA : IMessage
    {
        
public   void  SendMessage( object  msg)
        {
            
// 发送MOTOROLA短信;
        }
    }

    
public   class  SANSUNG : IMessage
    {
        
public   void  SendMessage( object  msg)
        {
            
// 发送SANSUNG短信;
        }
    }
}

语音接口如下:

namespace  XiaoXue
{
   
public   interface  ISound
   {
       
void  SendSound( object  Msg);
    }
}

语音具体类如下:

namespace  XiaoXue
{
    
public   class  NOKIASound : ISound
    {
        
public   void  SendSound( object  msg)
        {
            
// 发送NOKIA语音;
        }
    }

    
public   class  MOTOROLASound : ISound
    {
        
public   void  SendSound( object  msg)
        {
            
// 发送MOTOROLA语音;
        }
    }

    
public   class  SANSUNGSound : ISound
    {
        
public   void  SendSound( object  msg)
        {
            
// 发送SANSUNG语音;
        }
    }
}

装饰类(装饰并继承短信接口)如下:


namespace  XiaoXue
{
   
public   abstract   class  MessageClassDecorator:IMessage
   {
       
private  IMessage _messageClass;
       
public  IMessage messageClass
       {
           
get { return  _messageClass;}
       }
       
public  MessageClassDecorator(IMessage msgClass)
       {
           _messageClass
= msgClass;
       }
       
public   virtual   void  SendMessage( object  Msg)
        {
            _messageClass.SendMessage(Msg);
            
return ;
       }
    }
}

具体实现类如下:

namespace  XiaoXue
{
   
public   class  SoundMessageClassDecorator:MessageClassDecorator
   {
       
private  ISound _soundClass;
       
public  ISound soundClass
       {
           
get { return  _soundClass;}
           
set {_soundClass = value;}
       }
       
public  SoundMessageClassDecorator(IMessage msgClass): base (msgClass)
       {
       }
       
public   override   void  SendMessage( object  Msg)
        {
            _soundClass.SendSound(Msg);
            
base .SendMessage(Msg);
            
return ;
       }
    }
}


通过装饰模式,使用Nokia手机的追求者的发送短信的方法如下:

SoundMessageClassDecorator soundMessageClassDecorator = new  SoundMessageClassDecorator( new  NOKIA());
soundMessageClassDecorator.soundClass
= new  NOKIASound();
soundMessageClassDecorator.SendMessage(
" 小雪,元旦我们一起出去旅游吧 " );

 

你可能感兴趣的:(设计模式)