Class 面向对象设计为什么我们需要鸟类类的合成?
最近,我在一次采访中被问到一个问题,要设计一个鸟类飞行模拟器。 我继续思考模拟器类的策略模式和属性,如气压、风速等。一个方法将获取一个鸟对象和时间,并返回x、y、z坐标。 e、 g 然后想到了鸟类类: 对于bird can fly/Not fly属性,我考虑了一个在初始化时设置的布尔变量。例如:Class 面向对象设计为什么我们需要鸟类类的合成?,class,oop,design-patterns,composition,object-oriented-analysis,Class,Oop,Design Patterns,Composition,Object Oriented Analysis,最近,我在一次采访中被问到一个问题,要设计一个鸟类飞行模拟器。 我继续思考模拟器类的策略模式和属性,如气压、风速等。一个方法将获取一个鸟对象和时间,并返回x、y、z坐标。 e、 g 然后想到了鸟类类: 对于bird can fly/Not fly属性,我考虑了一个在初始化时设置的布尔变量。例如: class Bird attr_accessor :weight, :wing_dimension, :canfly, :height.... def initialize(weight, win
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类应该使用组合,并使用一个类来封装类中所需的属性
那么,我真的需要一个类来映射canfly行为吗?在这种情况下,我不能在创建Bird对象时初始化一个布尔字段
为什么这不是一个好的设计?
如果没有,最好的方法是什么?为什么?就OOD而言,比较关联/聚合、继承、组合和使用是很重要的。在组合关系中,类应该使用类的new方法创建对象实例 鸟类的种类与特定的体重和身高有关,就构成而言,一只鸟有两个翅膀和一个顶点,这可能是不同的种类。在Wing类中,Wing_维度属性应作为聚合关系包括在内,如bird类中的重量和高度
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
例如,在模拟器类中,如果您想要设计飞行模拟器,则该属性需要在不同的类中通用
综上所述,如果一般类之间存在继承关系,例如“Animal”与bird and fly(昆虫),则可以在def中建立聚合关系,并可以将fly作为Animal类的属性
class Simulator
attr_accesor :animal, :air_pressure, :wind_velocity
def map_coordinates(animal, time)
...
end
...
end
那么,我真的需要一个类来映射canfly行为吗?在这种情况下,创建Bird对象时,我不能只初始化一个布尔字段吗?
为什么这不是一个好的设计?如果不是,最好的方法是什么?为什么?
对于你的第一个问题:“我真的需要…?”这是一个非常好的回答
问题。就面向对象设计而言,这正是您需要问自己的问题。事实上,这正是做出好的设计决策的方式
您还得出了一个暂定解决方案“我能不能…?”这一事实意味着您已经确定了一个可以用二进制解决方案解决的小问题布尔会飞吗?正确:错误
让我们假设,您已经看到了全局。你想象你的“模拟器”会有各种各样的鸟,甚至是鸟
不能飞的鸟,以及那些典型的不能飞的鸟
最后,您将得出另外三个非常精彩的问题。我忍不住想知道你是不是直接从OOA&D教科书中提出了这些问题 1) 为什么这不是一个好的设计? 2) 什么是更好的设计? 3) 为什么第二种设计比第一种更好 好的,我会尽我最大的努力。我将试着从你问这些问题的方法和你所做的方式来做一个说明。看看所有这些问题在这里产生的微小足迹,与巨大足迹相比,它将出现在我的帖子中,试图填补所有这些空白,因为你不知道这些问题能产生多少答案(我也不知道)。这恰好是答案之一。伙计,我希望这不会变成一片混乱。(那是另一个) 首先,我想澄清一个非常重要的区别。
这些问题的性质与你期望在代数教科书中找到答案的问题的性质不同。代数是关于如何的。我发现为什么
在你学习微积分之前,在代数中没有任何意义 为什么不是这样…我应该用什么方法…怎么样那样更好…为什么那样更好我为什么要在乎这些是你在哲学教科书中找到答案的问题。它们也是面向对象设计的合适类型,因为面向对象设计与其说是一门“软科学”,不如说是一种哲学。这是我的观点,其他人持有这种观点,但也有人持相反的观点。那听起来像混凝土吗 有趣的是,这是一个在OOD中用来区分派生类和抽象类或接口的术语。这是结果,但不是设计。在我看来,理解第一个与任何具体的设计一样重要,如果不是更重要的话,有些人可能会把它当作一个好的答案 我还要问一个问题。您希望您的小的封装在代码库中,还是我的大的封装在代码库中?因为你可以做你想做的,那是你的选择。然而,让我指出一些可能会改变你想法的事情。我可以创建一个界面,比如说,我
可以这样称呼它 公共界面非常可能让您或其他任何人进行飞行操作想象{}您可能会说:这是一个可笑的冗长且过于描述性的命名约定!!!对此,我会回答:是的,但你甚至无法想象这个接口涵盖了多少内容……而且,我只需要写一次,因为这样我就可以做到……
我很有可能飞行操作你或其他任何人想象飞行
那我就把那个罐头放进去
class Simulator
attr_accesor :animal, :air_pressure, :wind_velocity
def map_coordinates(animal, time)
...
end
...
end