【问题标题】:class design in a little java, a little pattern?一点java中的类设计,一点模式?
【发布时间】:2016-01-31 06:20:44
【问题描述】:

我最近在看A Little Java, A Few Patterns,第3章介绍Pizza类及其一些子类。 CrustCheeseOlive 类被定义为 Pizza 的子类对我来说看起来很奇怪

显然,这些是披萨的成分,这些成分与披萨之间的关系是has a 而不是is a

那么为什么这些成分类被定义为 Pizza 的子类?

仅供参考,下面的代码 sn-p 是本书中使用的类结构。

【问题讨论】:

  • 我们看不到有问题的文字,所以只能猜测。我怀疑您误解了文字的内容;如果你没有,那么文本是错误的。这些都不是 Pizza 的子类。
  • 正如@chrylis 所说,Amazon.com 对这本书的评论是有争议的。有很多更好的书可以花时间阅读。

标签: java design-patterns computer-science


【解决方案1】:

它们听起来像是Pizza类型;这将使其成为 is-a 关系(mushroom pizzapizza)。

【讨论】:

  • 我不认为是这种情况。我已经上传了班级结构,如果你看看这本书并回答这个问题会更好
  • @JiacaiLiu 文本描述了一个通用的Pizza 类型,以及具体实现的子类。 Pizza<T>Olive<T> extends Pizza<T>PizzaCollection(具体来说,作者试图用generic types 解释builder pattern)。
  • 我还是想不通,在Cheese和其他子类中,为什么会有Pizza字段,这是builder模式的变种吗?
  • 真的没有明智的方法来理解class Crust extends Pizza.
  • @JiacaiLiu 地壳不是披萨(它是披萨的一部分)。继承被滥用。该设计不尊重Liskov substitution principle。这本书是 1998 年出版的。在流行的 GoF 书之后,几本“模式”书问世,乘风破浪。在我看来,很多都是/是浪费时间。如果你想要一些有价值的东西,我推荐 Head First Design Patterns。
【解决方案2】:

子类的名称有些误导。例如,Sausage 不是浇头;这是一个配上香肠的披萨,CheeseOliveAnchovy 也是如此。 Crust 真的是一个没有任何配料的披萨。以这种方式考虑比萨可以进行简单的递归描述:

  • 简单的外壳就是比萨饼。
  • 如果您在披萨上加奶酪,结果就是披萨。
  • 如果您在披萨上加香肠,结果就是披萨。
  • 如果您在披萨上加凤尾鱼,结果就是披萨。
  • 如果您在披萨上加橄榄,结果就是披萨。

Crust 是递归的基本情况,“toppings”对Pizza 进行递归调用。这就是为什么 'toppings' 有一个 Pizza 字段的原因:子类告诉您生成的比萨饼的最顶层是什么,而该字段告诉您下层是什么。

这也使得递归定义方法变得容易。假设我们要检查披萨是否是素食主义者:

  • 如果比萨是普通的外皮,那么就没有肉,所以比萨是素食的。 (基本情况:真)

  • 否则,披萨由顶层和子披萨组成。

  • 首先检查顶层。如果顶层是香肠或凤尾鱼,那么披萨就不是素食的。 (基本情况:假)

  • 否则,顶层是奶酪或橄榄。在这种情况下,当且仅顶层下方的子披萨是素食时,披萨是素食的。

  • 检查子披萨是否为素食。 (递归)

如果这些名称真的让您感到困扰,您可以将Crust 重命名为PizzaWithNoToppings,将Sausage 重命名为PizzaToppedWithSausage,等等。不过这些名字很丑,根本不适合像A Little Java这样的风格书籍。

【讨论】:

    【解决方案3】:

    虽然书名包含 Java,但它并不是一本关于 Java 的书。从表面上看,它是在教授使用 Java 进行函数式编程。

    这是理解这些示例的关键。例如,第一章实际上是关于 Union 数据类型(或 sum 数据类型),您通常会在 ML 等函数式编程语言中找到。

    在本书中,它没有使用任何集合概念,如集合、映射或列表。相反,作者教你创建这些概念。

    如果您熟悉 haskell 或 SML 中的列表类型,这些定义应该很自然。

    【讨论】:

      【解决方案4】:

      刘家才,我不知道这本书,但你的怀疑是有道理的。在编写良好的 OOP 代码中,Pizza 应该是一个包含一组成分的对象。并且在示例中扩展 Pizza 的每个类都应该实现成分接口:

      class Pizza {
        private Set<Ingredient> ingredients;
        //code
      }
      
      interface Ingredient {}
      
      class Crust implements Ingredient {}
      class Cheese implements Ingredient {}
      class Olive implements Ingredient {}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-20
        • 1970-01-01
        • 2012-08-19
        • 1970-01-01
        • 2011-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多