`
足至迹留
  • 浏览: 495201 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

装饰者模式(Decorator)

阅读更多
一、引入
本篇可以称为“给爱用继承的人一个全新的设计眼界”。我们即将再度探讨典型的继承滥用问题。你将在本章学到如何使用对象组合的方式,做到在运行时装饰类。一旦你熟悉了装饰的技巧,你将能在不修改任何底层代码的情况下,给你的对象赋予新的职责。

以StarBuzz咖啡店为例,他们原先的类设计是这样的:


但需求扩展,购买咖啡时,可以要求在其中加入各种调料,如豆浆Soy,蒸奶Streamd Milk, 摩卡Mocha等,Starbuzz会根据所加入的调料收取不同的费用,所以订单系统必须考虑到这些调料部分。
这是他们的第一个尝试:


这样是每个子类对应一种咖啡的搭配,一种价格的计算。
很明显,StarBuzz为自己制造了一个维护恶梦。如果牛奶的价钱上扬怎么办?新增一种焦糖调料风味怎么办?
造成这种维护上的困难,因为违反了我们之前提过的设计原则:
(1)没有分离变化和不变化的部分。
(2)没有使用组合代替继承。
我们不只一次说过,软件工程生命周期里,维护的代价是远高于开发代价的。就算是开发过程中,回头维护之前的代码都是有很高代价的。所以软件设计一定要考虑维护的方便性。很明显,充分应用设计原则(设计模式都是设计原则的具体应用)可以减轻维护工作量。

二、设计原则
此刻,我们再引入一个最重要的设计原则之一,开闭原则
类应该对扩展开放,对修改关闭。

这是应对“改变”的一个重要原则。要改变的时候应该是可以轻松扩展,而不是修改已有代码。如果你的需求有所改变,欢迎用任何你想要的行为来扩展我们的类。但不允许随意修改代码,我们花了许多时间得到了正确的代码,还解决了所有的bug,所以不让你修改现有的代码。

这乍听起来很矛盾,可是想想前面介绍的观察者模式,需要新增观察者时,不需要修改主题(Subject)就可以任何时候扩展观察者。我们本次要介绍的装饰者模式也是完全符合开闭原则的。
但是如何让设计的每个部分都遵循开放-关闭原则?通常这是办不到的。要让面向对象的设计同时具备开放性和关闭性,又不能修改现有的代码需要花费许多时间和努力。遵循开闭原则通常会引入新的抽象层次,增加代码的复杂度。我们需要把注意力集中在设计中最有可能改变的地方。然后应用开闭原则。

三、装饰者模式
结合上Starbuzz的咖啡问题,我们要采用不一样的做法:我们以饮料(Beverage类)为主体,然后在运行时以调料来装饰(decorate)饮料。比如,顾客想要摩卡和奶泡深焙咖啡,那么我们要做的是:
(1) 拿一个深焙咖啡(DarkRoast)对象
(2) 以摩卡(Mocha)对象装饰它
(3) 以奶泡对象(Whip)装饰它
(4) 调用cost()方法,并依赖委托(delegate)将调料的价钱加上去

下面看下设计:



好了,我们通过上面的例子已经知道:
(1) 装饰者和被装饰者对象有相同的超类型
(2) 可以用一个或多个装饰者包装一个对象
(3) 既然装饰者和被装饰者对象有相同的超类型,所以在任何需要原始对象(被包装的)的场合,可以用装饰过的对象代替它。
(4) 装饰者可以在所委托被装饰者的行为之前或之后加上自己的行为,以达到特定的目的。
(5) 对象可以在任何时候被装饰,所以可以再运行时动态地不限量地用自己喜欢的装饰者来装饰对象。


现在,我们可以试着定义下装饰者模式:
动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

下面我们看下装饰者典型的类图:


我们发现,这里面也用到继承了!!!!
仔细分析我们会发现我们用到继承只是达到装饰者和被装饰者是同一个超类型的目的,而不是想通过继承来获取行为。具体的行为是通过关联(组合)获取的。

真实世界里的装饰者
Java IO里装饰真模式应用很多,比如BufferedInputStream和LineNumberInputStream都是具体的装饰者类,继承自抽象的装饰类FilterInputStream。

四、总结
1.现在来看我们已经见过的设计原则:
(1)封装变化
(2)多用组合少用继承
(3)针对接口编程,不针对实现编程
(4)为交互对象的松耦合设计而努力
(5)对扩展开放,对修改关闭。

2.设计模式
(1)策略模式
(2)观察者模式
(3)装饰者模式

参考资料:
《HeadFirst》
  • 大小: 85.3 KB
  • 大小: 184.2 KB
  • 大小: 176.3 KB
  • 大小: 151.6 KB
  • 大小: 148.9 KB
0
2
分享到:
评论
2 楼 足至迹留 2014-08-07  
mfkvfn 写道
用数据库相关技术做多好。

还请细说下?利用关联关系吗?
1 楼 mfkvfn 2014-08-07  
用数据库相关技术做多好。

相关推荐

    装饰者模式——Decorator

    装饰者模式(Decorator)是一种设计模式,用于在运行时动态地给对象添加额外的责任或功能。它是结构型设计模式的一种,能将行为的增加与对象的创建分离,使得我们可以独立地扩展对象的功能。 在Java或其他面向对象...

    设计模式之装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern)是一种结构型设计模式,它在不改变原有对象的基础上,通过包裹一个对象并为其添加新的行为或责任,实现对对象功能的扩展。这种模式在软件开发中非常常见,尤其当需要在运行时动态改变...

    [结构型模式] head first 设计模式之装饰者模式(decorator)

    装饰者模式(Decorator Pattern)是结构型设计模式之一,它允许在运行时向对象添加新的行为或职责,而无需修改对象的源代码。这个模式的名字来源于装饰艺术,它通过添加额外的装饰来增强一个物体的外观,同样地,...

    装饰者模式(Decorator Pattern)原理图

    装饰者模式(Decorator Pattern)是一种结构型设计模式,它的定义是在不改变原有对象结构的基础上,动态地给该对象增加一些职责(即增加其额外功能)。这种模式允许向一个现有的对象添加新的功能,同时又不改变其...

    Head First 设计模式 (三) 装饰者模式(decorator pattern) C++实现

    装饰者模式(Decorator Pattern)是一种结构型设计模式,它允许我们向对象添加新的行为或职责,而无需修改对象的原始代码。在C++中实现装饰者模式,可以让我们灵活地扩展对象的功能,同时保持代码的可读性和可维护性...

    设计模式--装饰者模式java例子

    装饰者模式是软件设计模式中的一种结构型模式,它的主要目的是动态地给对象添加新的功能,而无需修改原有代码。在Java中,装饰者模式通常通过继承和组合来实现,它提供了一种比继承更灵活的方式来扩展对象的功能。...

    c++-设计模式之装饰模式(Decorator)

    装饰模式(Decorator Pattern)是一种结构型设计模式,允许在不改变对象接口的情况下,动态地为对象添加额外的职责或功能。装饰模式通常用于需要扩展对象功能而又不希望使用子类化的场景。 装饰模式的组成 组件接口...

    设计模式C++学习之装饰模式(Decorator)

    装饰模式(Decorator)是软件设计领域中一种非常实用的结构型设计模式,它允许我们向一个对象添加新的行为或责任,而无需修改该对象的源代码。在C++编程语言中,装饰模式常用于动态地扩展类的功能,使得类的行为在...

    PHP设计模式(八)装饰器模式Decorator实例详解【结构型】

    装饰器模式(Decorator Pattern)是一种结构型设计模式,主要用于在运行时动态地给对象添加新的职责或行为,而不必改变现有对象的类定义。在面向对象编程中,装饰器模式提供了一种相对于继承更加灵活的方式来增强或...

    Decorator装饰者模式

    在装饰者模式中,我们通常有两个主要的角色:Component(组件)和Decorator(装饰器)。Component是被装饰的对象接口,定义了所有装饰器和原始对象共同拥有的行为。Concrete Component是Component的具体实现,是实际...

    设计模式之装饰者(Decorator)

    装饰者模式是软件设计中的一种行为模式,它允许在运行时动态地给对象添加新的行为或职责,而无需改变对象的原始类。这种模式在不违反开闭原则的前提下,提供了扩展对象功能的能力,使得系统更加灵活,易于维护。 在...

    装饰器(Decorator)模式

    装饰器(Decorator)模式 装饰器(Decorator)模式是一种典型的结构型模式,主要用意是动态地为对象添加一些额外的功能。它提供了一个灵活的替代方案来继承子类,以扩展对象的功能。 在《Element of Reusable ...

    C#设计模式之Decorator 装饰模式

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它在不改变原有对象的基础上,通过添加额外的职责来扩展对象的功能。在C#中,装饰模式尤其适用于那些需要动态地增加或减少对象功能的情况,避免了使用...

    装饰者模式Demo

    装饰者模式是面向对象设计模式的一种,主要用于动态地给一个对象添加一些额外的职责,而不会改变该对象的类。这种模式允许我们独立于对象的类来扩展其功能,为对象增加新的行为或属性,同时保持了代码的可读性和可...

    结构型模式之装饰模式(Decorator)

    装饰模式(Decorator)是软件设计模式中的一种结构型模式,其主要目的是在不改变对象原有类的基础上,通过添加新的行为或职责来扩展对象的功能。这种模式使得代码的扩展性非常优秀,避免了由于频繁地使用继承而导致...

    装饰器模式[Decorator]

    装饰器模式(Decorator)是一种设计模式,它允许在运行时向对象添加新的行为或责任,而无需修改对象的源代码。这种模式属于结构型模式,是面向对象设计中的一种非常实用的技术。 装饰器模式的核心思想是通过将一个...

Global site tag (gtag.js) - Google Analytics