现在的位置: 首页 > 综合 > 正文

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

2012年02月08日 ⁄ 综合 ⁄ 共 2764字 ⁄ 字号 评论关闭

故事

      有一天,小雪的一个小学同学打电话告诉她,老同学马上要结婚了,婚礼将于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(
"小雪,元旦我们一起出去旅游吧");

 

抱歉!评论已关闭.