设计模式学习笔记(十)——Decorator装饰模式

Decorator 装 饰模式是一种结构型模式,它主要是解决:“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子 类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。继承为类型引入的静态特质的意思是说以继承的方式使某一 类型要获得功能是在编译时。所谓静态,是指在编译时;动态,是指在运行时。

GoF 《设计模式》中说道:动态的给一个对象添加一些额外的职责。就增加功能而言, Decorator 模式比生成子类更为灵活。

下面来看看 Decorator 模式的结构:



 

看这个结构好像不是很明白,下面我根据代码讲解一下这个结构。我想了一个场景:我们现在用的手机功能很多,我就用 Decorator 模式实现一下对某个手机的 GSP 和蓝牙功能扩展。

首先,我们需要一个手机的接口或者是抽象类,我这里就用抽象类来实现,代码如下:

public abstract class AbstractCellPhone

    {

        public abstract string CallNumber();

        public abstract string SendMessage();

}

AbstractCellPhone 也就是结构图中的Component ,然后,我再来实现NokiaMoto 的手机类,这类要继承AbstractCellPhone ,也就是图中ConcreteComponent 类要继承Component ,实现代码如下:

public class NokiaPhone : AbstractCellPhone

    {

        public override string CallNumber()

        {

             return "NokiaPhone call sombody" ;

        }

 

        public override string SendMessage()

        {

            return "NokiaPhone send a message to somebody" ;

        }

    }

 

    public class MotoPhone : AbstractCellPhone

    {

        public override string CallNumber()

        {

            return "MotoPhone call sombody" ;

        }

 

        public override string SendMessage()

        {

            return "MotoPhone send a message to somebody" ;

        }

  }   

接下来我需要一个Decorator 接口或者抽象类,实现代码如下:

public abstract class Decorator :AbstractCellPhone

    {

        AbstractCellPhone _phone;

 

        public Decorator(AbstractCellPhone phone)

        {

            _phone = phone;

        }

 

        public override string CallNumber()

        {

            return _phone.CallNumber();

        }

 

        public override string SendMessage()

        {

            return _phone.SendMessage();

        }

  }

正如结构图中,这个Decorator 即继承了AbstractCellPhone ,又包含了一个私有的AbstractCellPhone 的对象。这样做的意义是: Decorator 类又使用了另外一个 Component 类。我们可以使用一个或多个 Decorator 对象来“装饰”一个 Component 对象,且装饰后的对象仍然是一个 Component 对象。 在下来,我要实现GSP 和蓝牙的功能扩展,它们要继承自Decorator ,代码如下:

public class DecoratorGPS : Decorator

    {

        public DecoratorGPS(AbstractCellPhone phone)

            : base (phone)

        { }

 

        public override string CallNumber()

        {

            return base .CallNumber() + " with GPS" ;

        }

 

        public override string SendMessage()

        {

            return base .SendMessage() + " with GPS" ;

        }

     }

 

    public class DecoratorBlueTooth : Decorator

    {

        public DecoratorBlueTooth(AbstractCellPhone phone)

            : base (phone)

        { }

 

        public override string CallNumber()

        {

            return base .CallNumber() + " with BlueTooth" ;

        }

 

        public override string SendMessage()

        {

            return base .SendMessage() + " with BlueTooth" ;

        }

  }

最后,用客户端程序验证一下:

static void Main(string [] args)

        {

             AbstractCellPhone phone = new NokiaPhone ();

            Console .WriteLine(phone.CallNumber());

            Console .WriteLine(phone.SendMessage());

            DecoratorGPS gps = new DecoratorGPS (phone);     //add GSP

            Console .WriteLine(gps.CallNumber());

            Console .WriteLine(gps.SendMessage());

            DecoratorBlueTooth bluetooth = new DecoratorBlueTooth (gps); //add GSP and bluetooth

            Console .WriteLine(bluetooth.CallNumber());

            Console .WriteLine(bluetooth.SendMessage());

            Console .Read();

      }

执行结果:

NokiaPhone call sombody

NokiaPhone send a message to somebody

NokiaPhone call sombody with GPS

NokiaPhone send a message to somebody with GPS

NokiaPhone call sombody with GPS with BlueTooth

NokiaPhone send a message to somebody with GPS with BlueTooth

 

从执行的结果不难看出扩展功能已被添加。最后再说说 Decorator 装饰模式的几点要点:

1 、通过采用组合、而非继承的手法, Decorator 模式实现了在运行时动态的扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了单独使用继承带来的“灵活性差”和“多子类衍生问题”。

2 Component 类在 Decorator 模式中充当抽象接口的角色,不应该去实现具体的行为。而且 Decorator 类对于 Component 类应该透明——换言之 Component 类无需知道 Decorator 类, Decorator 类是从外部来扩展 Component 类的功能。

3 Decorator 类在接口上表现为 is-a Component 的继承关系,即 Decorator 类继承了 Component 类所具有的接口。但在实现上又表现为 has-a Component 的组合关系,即 Decorator 类又使用了另外一个 Component 类。我们可以使用一个或多个 Decorator 对象来“装饰”一个 Component 对象,且装饰后的对象仍然是一个 Component 对象。(在这里我想谈一下我的理解:当我们实例化一个 Component 对象后,要给这个对象扩展功能,这时我们把这个 Component 对象当作参数传给 Decorator 的子类的构造函数——也就是扩展方法的功能类。对于引用类型传参时,实际上只是传递对象的地址,这样,在功能扩展是,操作的应该是同一个对象)

4 Decorator 模式并非解决“多子类衍生的多继承”问题, Decorator 模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。 Decorator 是在运行时对功能进行组合。

 

http://www.cnblogs.com/kid-li/archive/2006/06/26/435966.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值