1 实际中的面向对象
虽然现实场景往往比预想的要复杂得多。但是由于面向对象提供易理解可重用,可维护性,使代码更易于其他开发人员理解和维护,面向对象方法正变得越来越流行。
即使如此要成功实践该方法并不是一件容易的事情,这里先简单介绍执行的步骤,然后通过一个时钟的案例说明如何在实际场景匹配面向对象的特性。
最后强调命名对重用和维护的重要性,并提供三种命名方式,并简单说明OO的优缺点。
2 执行步骤的分歧
面向对象分析 Object-Oriented Analysis经典OOA 由三个步骤组成
-- 1 用例建模
-- 2 类建模
-- 3 属性方法建模
当代OOA 有五个步骤
① 确认对象和类。
② 确认结构。
结构是指问题域的复杂性和连接关系。类成员结构反映了泛化-特化关系,整体-部分结构反映整体和局部之间的关系。
③ 确认主题。主题是指事物的总体概貌和总体分析模型。
④ 确认属性。
⑤ 确认方法。
- 综合以上,避开陷阱的方式如下:
首先要清楚地了解您要解决的问题。这将帮助您识别关键对象及其关系。
其次使用 UML或者sysML3(建模语言)创建表示对象及其关系的关系图。这可以帮助您可视化系统并识别任何潜在的设计问题。
再次遵循标准设计模式和原则(如SOLID),以确保代码是模块化的、可扩展的和可重用的。
最后彻底测试您的代码,以确保其正常运行并满足系统的要求
3 使用OO分析面向对象特性:封装,继承,多态
假设我们所在工厂需要设计一个设备,需要该设备告诉您时间、温度、压力和湿度。
而你正好负责该设备的设计。该设备告诉用户时间、温度、压力和湿度,当完成设备生产时,用户会看到四个仪表告知四条数据。
用户不会知道设备里面有什么,或者显示的数字是如何确定的。 获取此数据的实现是封装的。 用户所看到的(以及用户想要/需要看到的)就是界面。
有朝一日,设计师可能会改变一种仪表,使其更准确或更便宜。 而你不必更改界面,用户也永远不会知道发生了更改。
- 多态
如果用户想要两个天气时钟,一个用于客厅,一个用于厨房怎么办? 只需再购买一个漂亮的时钟设备实例------拥有两个时钟。
但是它们是不同的,显示不同的数据,在不同的地方,具有不同的身份,做同一件事,一个可以现实天气温湿度的时钟。 仅仅因为用户需要拥有其中两个,并不意味着工厂必须重新发明一个新的天气时钟。
工厂只需为用户生产了另一个。由于市面上的用户已经拥有一个,在厨房中使用新的很容易-因为界面是相同的。实现是一样的吗?
如果用户转而回到市场上并购买数字手表怎么办? 假设工厂为了省钱,在手表和天气时钟中使用相同的计时机制和界面。
- 继承
我们可以通过识别它们相似的原因来对这些设备进行分类:它们都是钟表类型。 数字手表只有时间功能。天气时钟会做更多的事情,但它也会保留和显示时间。
用户认为工厂喜欢为这两款产品重新设计计时机制的想法吗?当然不,所以你只需重复使用该部分。
我们在 OO 中通过形成继承层次结构来做到这一点。 可能有读者听说过这个层次结构的术语"isa",因为我们可以说天气时钟是一个计时器( Time Piece)(请注意,在这种情况下,最好说天气时钟至少是一类计时器).
markdown
计时器 TimePiece
/ \
DigtalWatch WeatherCiock
数字时钟 天气时钟
上图展示了计时器,数字时钟,天气时钟 的继承层次结构,那么问题来了
计时器TimePiece中需要有什么?
数字时钟DigitalWatch 中需要有什么?
天气时钟WeatherClock 中需要有什么?
- 封装
有人会购买计时器产品吗? 假设您有一个连接到设备的串行接口。您想从他们那里获取当前时间。
在面向对象方法OO中,你发送了一条消息。消息需要不同吗?不需要,当它要求提供相同的信息时,为什么要这样发不同消息?
假设你可以生产气压计和湿度计。如果重新发明轮子并拥有两个气压计,一个用于独立使用,一个嵌入天气时钟,这不是很麻烦吗?
我们可以通过继承来避免这种情况吗?不,我们需要另一种手段:封装。我们可以在另一个对象中嵌入、包含或组合一个对象。
经过一番分析后,可以得到基本的用例图。
4 名称很重要:命名方案
类、对象、实例变量和方法的标准命名方案非常重要。这里有两种选择。
- 命名方案 1
类名:连接的单词,每个单词都以大写字母开头。
帐户、银行帐户、CashDispenser、SortedIntegerQueue 宾语、ivar、方法:串联的单词,第一个单词全部小写,后续单词以大写字母开头。
balance, share余额, count, quantityOfFives 列表、节点列表、帐户、newAcct 存款, 余额, 对象At, 分配货币
- 命名方案 2
类名:连接的单词,每个单词都以大写字母开头。
帐户、银行帐户、CashDispenser、SortedIntegerQueue 对象:用下划线分隔的小写字母。
列表、node_list、帐户new_acct Ivars:小写,用下划线分隔。
平衡、share_balance、计数quantity_of_fives 方法:串联词,第一个词全部小写,后续词以大写开头,
存款, 余额, 对象At, 分配货币
- 匈牙利语符号
所有东西都有一个标识它的标签。此标记将追加到名称中,因此,例如,可以称 float 类型的名为 height 的 ivar height_i_f。同样,每个类都以大写字母"C"结尾。
该方案迫使您进入解决方案空间(编程语言),并分散您对问题空间的注意力。
名称至关重要,原因与它们在非面向对象语言中很重要的原因相同,但也因为面向对象编程的拟人化性质。
在面向对象语言中,通常使用类名和定冠词或不定冠词(Control,aController;视图,视图)。当找不到更合适的名称(列表、员工)时,这些名称很好。
5 小结 优缺点和参考
一 面向对象分析和设计的优点:
模块化:面向对象允许您将复杂的系统分解为更小、更易于管理的部件或对象。随着时间的推移,这使得开发、测试和维护代码变得更加容易。
可重用性:由于面向对象强调模块化设计,因此您通常可以在不同的项目或应用程序中重用代码。这可以节省时间和精力,还可以提高代码的整体质量。
可扩展性:面向对象可帮助您设计可扩展的软件,这意味着它可以处理增加的负载或功能,而无需对代码库进行重大更改。
可理解易维护:通过使用标准的面向对象 技术和设计模式,易于维护。
二 面向对象分析和设计的缺点:
在 OOAD 中,任何时候都很难确定系统所需的所有必要类和对象。 我们的大多数项目开发团队都熟悉传统的分析和设计。
OOAD 提供了一种新型的项目管理方式。 这就是为什么可能很难在估计的时间和预算内完成解决方案的原因。 如果没有明确的重用过程,这种方法一般不会导致大规模的成功重用。
- 参考书目:
《面向对象开发的陷阱》 -- 布鲁斯.韦伯斯特 Bruce Webster