【问题标题】:Object Orient Design Why we need composition for Bird class?面向对象设计 为什么我们需要对 Bird 类进行组合?
【发布时间】:2017-05-11 15:35:49
【问题描述】:

最近我在一次采访中被问到一个设计鸟类飞行模拟器的问题。 我继续思考模拟器类的策略模式和气压、风速等属性。一个方法需要一个鸟对象和时间,并返回 x、y、z 坐标。 例如

class Simulator
 attr_accesor :bird, :air_pressure, :wind_velocity

 def map_coordinates(bird, time)
  ...
 end
 ...
end

然后想到鸟类:

对于鸟可以飞/不飞的属性,我想到了一个布尔变量,它将在初始化时设置。例如:

class Bird
 attr_accessor :weight, :wing_dimension, :canfly, :height....

 def initialize(weight, wing_dimension, canfly, height)
  @weight = weight
  @wing_dimension = wing_dimension
  @canfly = canfly
  @height = height
 end 
end

我的问题是从OOD的角度来看,它说Bird类应该使用组合并使用类来封装类中所需的属性。 https://www.safaribooksonline.com/library/view/head-first-design/0596007124/ch01.html

那么,我真的需要一个类来映射 canfly 的行为吗?在这种情况下,在创建 Bird 对象时,我不能只初始化一个布尔字段。

为什么这不是一个好的设计? 如果不是,最好的方法是什么?为什么?

【问题讨论】:

  • 为什么飞行模拟器会有不会飞的鸟的实现?
  • 确实!但是面试官问了这个问题……你会怎么做一个不会飞的鸟鸡的对象
  • @jaco0646 为什么我们不能在 Bird 类中使用布尔变量而不是单独的类进行组合?

标签: class oop design-patterns composition object-oriented-analysis


【解决方案1】:

就OOD而言,重要的是在关联/聚合、继承、组合和使用之间进行比较。在组合关系中,类应该使用类的方法 new 创建对象实例。

鸟类具有特定的体重和高度,就构成而言,一只鸟有两个翅膀和一个峰,它们可能是不同的类。在 Wing 类中,wing_dimension 属性应作为聚合关系包含在内,在鸟类中应作为体重和高度。

class Bird
 attr_accessor :weight, :height, :rightWing, :leftWing, :peak

 def initialize(weight, height)
  @weight = weight
  @height = height
  rightWing = Wing. new
  leftWing = Wing. new
  peak = Peak.new
 end 
end

例如,在 Simulator 类中,如果你想设计一个飞行模拟器,这个属性需要在不同的类中是通用的。

综上所述,如果一个通用类之间存在继承关系,例如“Animal”与bird和fly(insect),可以在def中做一个聚合关系,canfly作为一个Animal 类的属性。

class Simulator
 attr_accesor :animal, :air_pressure, :wind_velocity

 def map_coordinates(animal, time)
  ...
 end
 ...
end

【讨论】:

    【解决方案2】:

    那么,我真的需要一个类来映射 canfly 的行为吗?在这种情况下,我不能在创建 Bird 对象时只初始化一个布尔字段吗?

    为什么这不是一个好的设计?如果不是,最好的方法是什么?为什么?

    对于您的第一个问题:“我真的需要……吗?”这是一个真的好 问题。就面向对象设计而言,这正是您需要问自己的问题。事实上,这正是做出好的设计决策的方式。

    事实上,您还得出了一个暂定的解决方案“我不能……吗?”表示您已经确定了一个小问题,您可以使用二元解决方案来解决。 bool canfly ?真:假

    让我们假设,您已经看到了全局。你想象你的“模拟器”会有各种各样的鸟,甚至是鸟 不会飞的鸟,以及那些会飞的典型鸟。

    最后,您提出了另外三个非常棒的问题。
    我不禁想知道您是否直接从 OOA 和 D 教科书中提取了这些问题。

    1) 为什么不是一个好的设计?

    2) 什么是更好的设计?

    3) 为什么第二种设计会比第一种更好

    好的,我会在这里尽力而为。我将尝试从您的 提出这些问题的方法以及您所做的方式中进行说明。看看所有这些问题在这里留下的微小的足迹,与它在我的帖子中试图填补的巨大的足迹相比在所有这些空白中,因为您不知道这些问题会产生多少答案(我也不知道)。这恰好是一个的答案。伙计,我希望这不会变成一团糟。(那是另一个)

    首先,我想澄清一个非常重要的区别。
    这些问题的性质与您期望在代数教科书中找到答案的问题的性质不同。代数是关于HOW。我发现为什么
    在你学习微积分之前,它在代数中没有任何意义。

    为什么不是这样...我应该怎样...如何这样更好...为什么 这样更好吗...? 为什么我什至应该关心? 这些是您在哲学教科书中找到答案的问题。它们也适合 OOD,因为 OOD 更像是一种哲学,而不是“软科学”。这是我的观点,其他人也持这种观点,但也有人不这么认为。这听起来具体吗?

    有趣的是,这是 OOD 中用来区分派生类与抽象类或接口的术语。这是结果,但它不是设计。在我看来,首先理解这一点与任何具体设计一样重要,有些人可能会试图将其作为一个好的答案。

    我也问一个问题。您希望在您的代码库中使用您的tiny 足迹还是我的HUGE 足迹?因为你可以做你想做的,那是你的选择。但是,让我指出一些可能会改变你想法的事情。我可以创建一个接口,比如说,我
    可能会这样称呼它。

    public Interface IEveryPossibleFlyingOperationYouOrAnyoneElseMightImagine{}; 你可能会说:你的命名约定太长而且描述性太强了!!!我会回复: 是的,但是你甚至无法想象 Interface 涵盖了多少东西。...而且,我只需要写一次,因为那样我就可以做到...... .
    IEveryPossibleFlyingOperationYouOrAnyoneElseMightImagine fly;
    然后我会把那个小小的fly(也是一种碰巧会飞的昆虫)放在我的代码库中。然后,我会关闭它,希望永远不必再打开它。

    此外,属于该接口的所有内容,您对它一无所知,因为它已被抽象出来,并且与其他类似的东西松散耦合,为了将来可能的扩展,永远不会破坏您的代码库。怎么可能?这是一只小小的苍蝇。

    您会看到这个答案有多长,我向您保证,它只是触及了您在这里实际提出的问题的表面。

    现在,我将尝试为您提供一些更具体的内容,尽管这还不足以满足您在这里提出的所有要求。

    一般来说,OOP 涉及很多事情,我希望这件事至少有一定的意义,它是一个原则。如果学习并遵循该原则,您将永远不会在您的代码库中留下我的足迹。

    该界面背后的奥秘是您的客户永远不必知道的事情,但我向您保证,它的组合方式使其具有极强的通用性和适应性,因为我根据尝试构建它以及其他人比我聪明得多的经过验证的原则和模式。

    即使他们也不知道这种范式的所有可能性,因为实在太多了。无论如何,他们并不关心,因为他们正忙于通过混合和匹配原则和模式来解决其他设计问题,非常简单地解决非常复杂的问题。

    另外,得到这个,下次你开始设计一些东西时,你可以把那只小苍蝇放进去并在那里使用它,而且永远只有一个地方可以去维护和改进所有的东西在那只小小的苍蝇后面。

    我知道这可能不是您正在寻找的答案,或者您可能已经得到它,这太棒了。我花了很长时间才弄清楚一个物体到底是什么……但是一旦它点击,在一位非常聪明的教授的帮助下,他向我展示了我试图在这里展示的东西;哦.. 还有一本叫《四人帮》的书;然后我就可以开始了,我只希望我也能理解这一切。

    我想如果你回去看看那篇文章,你将能够弄清楚其他答案是什么,我只回答了简单的一个(或尝试过)。我看了看,所有的信息都在那里。可能你只需要以稍微不同的方式看待它,但如果你真的想知道,你就会得到它。

    我很抱歉,但这是我能做的最好的,同时也是诚实的。如果有人试图告诉你 HOW 是答案,而不是 WHY,请不要听他们的,因为他们可能也不理解,但不是因为它是难的。那是因为他们没有像你在这里那样开始问正确的问题。我祝你好运,并希望其他人能比我更好地解释它。 +1) 提出所有正确的问题!

    【讨论】:

      猜你喜欢
      • 2022-12-05
      • 2019-09-26
      • 2013-02-08
      • 1970-01-01
      • 2011-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多