1.7 案例学习
我们的案例学习将会跨越本书的多个章节。我们将会从不同的角度深入研究同一个问题。多次寻求不同的设计和设计模式是非常重要的。我们将会给出不唯一的正确答案:有多个不错的答案。我们的意图是提供一个真实的案例,它具有现实中的深度和复杂度,会给我们带来一些很难抉择的难题。我们的目标是帮助读者应用面向对象编程和设计概念。这意味着选择不同的技术方案来创建有用的软件。
这个案例学习的第一部分是问题的概述和目标。问题的背景会涵盖多个方面,以便我们在后面的章节中设计和构建解决方案。概述部分会用一些UML图来描绘要解决问题的要素。这些UML图会随着我们在后面的章节中细化设计和改变设计而不断演化。
就像很多现实中的问题一样,作者也会带入一些个人的偏见和假设。关于技术可能带来的偏见,可以考虑阅读相关的图书,比如Sara Wachter-Boettecher的Technically Wrong。
我们的用户想要自动化一个通常被称作分类(classification)的工作。这是支撑产品推荐的观念:上次,一个用户购买了产品X,所以他可能对相似的产品Y有兴趣。我们已经根据他们的喜好进行了分类,因此可以定位同类产品中的其他产品。这个问题可能会涉及复杂的数据组织问题。
从一个更小和更可控的问题开始会比较容易。用户最终希望能够给各种复杂的消费类产品分类,但意识到解决一个困难的问题并不是学习如何构建这类应用的好方法。最好从一些复杂程度可控的东西开始,并优化和扩展,直到可以应对所有需要解决的问题。因此,在这个案例学习中,我们将构建一个鸢尾花的分类器。这是一个经典的分类问题,已经有很多相关文章讨论如何给鸢尾花做分类。
我们需要一套训练集,其分类器可作为正确分类鸢尾花的示例。我们会在下一节讨论训练数据是什么样的。
我们会用UML创建一系列的图来描述和总结我们将要创建的软件。
我们将使用一种被称为4+1视图的技术来研究这个问题。这些视图包括:
• 数据实体的逻辑视图(Logic View),包括它们的属性和它们之间的关系。这是面向对象设计的核心。
• 描述如何处理数据的过程视图(Process View)。这可能需要多种形式,包括状态图、活动图和序列图等。
• 代码组件的开发视图(Development View)。该图展示了软件组件之间的关系,描述了类定义是如何被组织到不同的模块和包中的。
• 展示应用程序集成和部署的物理视图(Physical View)。如果应用程序遵循通用的设计模式,则物理视图不是必需的。否则,有必要使用物理视图展示各个组件是如何集成和部署的。
• 上下文视图(Context View)为其他4个视图提供了统一的上下文。上下文视图通常会描述使用系统的参与者,这可能涉及用户及自动化接口。这些都属于系统的外部,系统必须响应这些外部参与者。
我们通常会先画上下文视图,这样我们就可以知道其他视图的作用。随着我们对用户和问题领域理解的演化,上下文也会演化。
所有这些4+1视图是一起演化的,认识到这一点非常重要。一个视图的变化通常会反映在其他视图中。一个常见的错误是认为其中一种视图是根基,其他视图基于它之上一层一层地构建,最终开发出软件。
在开始分析和设计软件之前,我们先介绍一下问题的背景和基本信息。