装饰图案|第1组(背景)

要理解装饰师模式,让我们考虑一个灵感来自于书的“首部设计模式”。假设我们正在为一家披萨店构建一个应用程序,我们需要对他们的披萨类进行建模。假设他们提供四种类型的披萨,即活力派披萨、农舍披萨、玛格丽塔披萨和鸡肉嘉年华披萨。最初,我们只是使用继承并抽象出 披萨 上课。

null

pizza1

每个披萨都有不同的价格。我们已经覆盖了子类中的getCost()以找到合适的成本。现在,假设有一个新的要求,除了一个披萨,顾客还可以要求几种配料,如新鲜番茄、烤盘、墨西哥胡椒、辣椒、烧烤、,等等。让我们思考一下,我们如何适应上述类别的变化,以便客户可以选择带配料的披萨,我们得到客户选择的披萨和配料的总成本。

让我们看看各种选择。

选项1 为每个披萨配料创建一个新的子类。类图如下所示: pizza2

这看起来很复杂。有太多的类,是一个维护噩梦。此外,如果我们想添加新的配料或披萨,我们必须添加这么多的课程。这显然是非常糟糕的设计。

选项2: 让我们将实例变量添加到pizza基类中,以表示每个pizza是否都有顶部。类图如下所示: pizza3

超类的getCost()计算所有配料的成本,而子类中的一个加上特定披萨的成本。

// Sample getCost() in super class
public int getCost()
{
    int totalToppingsCost = 0;
    if (hasJalapeno() )
        totalToppingsCost += jalapenoCost;
    if (hasCapsicum() )
        totalToppingsCost += capsicumCost;

    // similarly for other toppings
    return totalToppingsCost;
}
// Sample getCost() in subclass
public int getCost()
{
    // 100 for Margherita and super.getCost()
    // for toppings.
    return super.getCost() + 100;
}

这个设计一开始看起来不错,但让我们看看与之相关的问题。

  • 配料的价格变化将导致现行规范的变更。
  • 新的toppings将迫使我们在超类中添加新方法并改变getCost()方法。
  • 对于一些披萨,有些配料可能不合适,但子类继承了它们。
  • 如果顾客想要双份辣椒或双份芝士汉堡呢?

简而言之,我们的设计违反了最流行的设计原则之一—— 开闭原理 声明类应该为扩展而打开,为修改而关闭。

在下一集中,我们将介绍Decorator模式,并将其应用于上述问题。

参考资料: 首当其冲的设计模式(书)。

本文由 苏拉布·库马尔 .如果你喜欢GeekSforgek,并且想贡献自己的力量,你也可以写一篇文章,并将文章邮寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享