Head First Design Patterns 阅读笔记之三: Decorator Pattern

来源:互联网 发布:人工智能理论 编辑:程序博客网 时间:2024/06/05 19:11

欢迎来到 Starbuzz Coffee

星巴克作为一家扩展最快的咖啡店,它们现在需要更新饮料订购系统以便满足现在庞大的需求。这个订购系统的第一版如下:
first edition

显然这对于日后的维护来说,完全是个噩梦。这里需要提到一个设计原则(Open-Closed Principles):

类应当对扩展开放,对修改封闭
Classes should be open for extension, but closed for modication.

我们的目标是让类易于扩展以便包含新的行为,同时不去修改现存的源代码。但是并不是在每个部分都要采用这一原则,如果到处滥用,反而会导致代码复杂。一般在代码最重要并且会变化的地方采用这一原则。


使用 Decorator Pattern

如果一个顾客需要 Dark Roast,加 Mocha 和 Whip。我们这么做:

  • Take a DarkRoast object
  • Decorate it with a Mocha object
  • Decorate it with a Whip object
  • Call the cost() method and rely on delegation to add on the condiment costs

但是这里的 decorate 怎么做?我们可以把它看做封装器(wrapper)。

Decorator

下面给一个正式的定义:

The Decorator Pattern attaches additional reponsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

下面给一个图像实例:
图像实例

而在之前的情境下,可以画出如下框架:
Starbuzz beverge

public abstract class Beverage{    String description = "Unknown Beverage";    public String getDescription()     {         return description;    }    public abstract double cost();}// 与此类似实现咖啡类 HouseBlend,Espresso,Decaf 类public class DarkRoast extends Beverage{    public DarkRoast()     {         description = "Dark Roast Coffee";    }    public double cost()    {        return 0.99;    }}
public abstract class CondimentDecorator extends Beverage{    public abstract String getDescription();}// 与此类似实现调料类 SteamMilk,Soy,Whip 类public class Mocha extends CondimentDecorator{    Beverage beverage;    public Mocha(Beverage beverage)     {         this.beverage = beverage;    }    public String getDescription()     {        return beverage.getDescription() + ", Mocha";    }    public double cost()     {        return .20 + beverage.cost();    }}
// 测试public class StarbuzzCoffee{    public static void main(String[] args)    {        Beverage beverage = new Espresso();         System.out.println(beverage.getDescription() + " $" + beverage.cost());        Beverage beverage2 = new DarkRoast();        beverage2 = new Mocha(beverage2);         beverage2 = new Mocha(beverage2);         beverage2 = new Whip(beverage2);        System.out.println(beverage2.getDescription() + " $" + beverage2.cost());        Beverage beverage3 = new HouseBlend();         beverage3 = new Soy(beverage3);          beverage3 = new Mocha(beverage3);          beverage3 = new Whip(beverage3);        System.out.println(beverage3.getDescription() + " $" + beverage3.cost());    }}

现实中的 Decorators:Java I/O,Java I/O 大量使用了 Decorator Pattern。但是 Java I/O 也指出了 Decorator Pattern的一个问题:使用这个模式会有很多小类,这会让使用者感到恐慌。

0 0
原创粉丝点击