软件设计与数据结构

Chapter 6 Ethics and Design

| 关于   «  1. 伦理   ::   目录   ::   3. 实验 6 数组栈  »

2. 软件设计与 MVC

2.1. 目标

完成本模块后,学生将能够:

  • 识别功能需求与非功能需求

  • 从文档化需求中识别类、字段、方法及类之间的关系

  • 描述使用设计模式的目的与益处

  • 解释并使用 MVC 与观察者设计模式

  • 应用并展示良好的设计实践

  • 使用 UML 类图产出软件系统的设计

2.2. 交互式:软件设计导论

Follow Along and Engage

下载与视频对应的幻灯片。观看视频时在其上做笔记,并亲自练习绘制图表!

IntroToSoftwareDesign.pdf

2.3. 功能需求与非功能需求

如果您曾受命设计某个软件产品,却发现自己手头只有一份描述该拟议软件产品的高层概述,那么从 识别 并 记录 潜在的功能性与非功能性需求开始您的分析与设计,或许是个好主意。

这可能有助于您更好地构想软件产品、软件可能支持的不同用户和流程,以及软件中预期的各种操作和功能。至少,此练习将为您后续与利益相关者和用户的讨论提供一个起点,有望促成更详细的需求收集。

请注意,功能需求和非功能需求将在其他课程中进行更深入的探讨。

目前,对这些要求的总体理解就足够了。

回顾下面提供的功能需求和非功能需求的描述与示例。

2.3.1. 功能需求

这些是规定给定系统或软件产品 应该 做什么的需求。功能需求通常表述为“系统应执行'<requirement>'"的形式。

关于 电子商务解决方案(在线店面),功能需求的一些示例可以是:

系统应允许用户 ________

  • 根据特定搜索条件(例如名称、描述或产品标识符)搜索产品

  • 查看产品详情

  • 将产品添加到购物车

  • 从购物车中移除产品

系统应允许已注册客户 ________

  • 下订单

  • 提交付款

  • 查看订单详情

  • 登录账户(登入)

  • 管理账户资料

  • 更改密码

关于图书馆管理系统,功能需求的一些示例可以是:

系统应允许读者(即使用图书馆的人)________

根据特定搜索条件(例如按书名、作者或 ISBN)搜索图书

  • 查看图书详情

  • 预约图书

  • 借阅图书

  • 归还图书

2.3.2. 非功能性需求

功能需求规定系统 应该做什么,而非功能需求则规定系统应该如何做,即给定的系统或软件产品应如何执行其各项功能。非功能需求通常指定质量属性,包括与可用性、性能、可靠性、安全性、可维护性等相关的属性。

关于 电子商务解决方案(在线店面),非功能性需求的一些示例可以是:

系统应 ________

  • 在 2018 年之后发布的所有浏览器及浏览器版本上正常运行

  • 采用响应式设计

  • 在 2 秒内完成(并提供结果)用户发起的搜索

  • 能够每小时处理 1000 万用户,且性能/用户响应时间不下降

  • 仅接受长度至少为八 (8) 个字符且包含至少一个大写字母、一个特殊字符和一个数字的账户密码

关于 图书馆管理系统,非功能性需求的一些示例可以是:

系统应 ________

  • 在最大响应时间 4 秒内完成(并确认成功或失败)用户发起的请求

  • 支持跟踪和管理至少 100,000 本图书馆藏书及相关图书馆媒体

  • 支持每分钟高达 5000 次读者请求

  • 便于具备基本计算机素养的人员使用(浏览器、网页浏览、文字处理、搜索引擎等)

  • 对所有相关操作包含验证检查、用户确认提示及其他提示,以帮助人们避免犯错

2.4. 检查点 1

2.5. 识别类、字段和方法

使用 UML 类图设计软件产品的第一步是审查已文档化的需求,目标是识别系统的类、字段和方法。第一步是审查软件需求并记录所有的名词、动词、过程和概念。

回想一下,类是对象的蓝图或规范。它们通常是具有属性(数据/信息片段,通常称为字段)和行为(方法)的感兴趣实体,这些属性和行为是软件按预期运行所必需的。

2.5.1. 识别类与字段

类与字段源自我们软件需求文档中的名词和名词短语。其中一些也可以通过考虑我们的软件产品将如何使用、该软件旨在支持的流程以及软件的用户来发现。

名词和名词短语要么指代系统关注的实体(事物),要么指代与这些实体关联的单个数据/信息片段。

因此,名词和名词短语是类或类的字段的合适候选。

2.5.2. 区分哪些名词是类,哪些是字段

一旦你记录了所有名词,接下来就需要确定哪些是类,哪些是字段。以下规则将帮助你区分类与字段。

  • 指代具有多个关注属性的实体(事物)的名词和名词短语最有可能是类

  • 指代单个属性或数据项的名词和名词短语最有可能是某个类的字段

2.5.3. 数据结构

确定是否有任何类需要与另一个类的单个实例或多个实例进行交互(或管理)。

如果需要许多实例,则应考虑是否可以使用数据结构来管理这些实例。下一步是评估并选择一种或多种数据结构,以提供符合预期系统需求的操作和特性。

2.5.4. 识别类的方法

方法源自审查软件需求文档并考虑软件拟支持的流程时所发现的动词和动词短语。

动词和动词短语暗示了类的职责,这些将帮助你推导出方法。

请记住,每个类都应遵循单一清晰的抽象,即一组相关的职责。此外,每个方法都应出色地执行或完成一项任务。

将动词和动词短语归类到应负责执行这些动作或任务的类下。这些很可能是该类的方法。请记住,一个类通常应负责管理自身及其字段。

2.5.5. 访问修饰符与类、字段及方法的可见性

访问修饰符允许开发者指定其他类是否可以使用给定类的特定字段或调用其特定方法。

新开发者经常忘记为类、字段和方法指定访问修饰符。

这是一种不良习惯,应当避免,因为省略访问修饰符可能导致某些意外行为,破坏封装性,并可能允许外部类以非预期的方式访问字段和方法。

在描绘软件设计和开发软件解决方案时,都应始终为所有类、字段和方法指定访问修饰符。

Access Modifiers

访问修饰符 / 可见性修饰符

同类

同包

包外

全局

备注

未设置 例如,有些开发者会声明一个像 int print(int n) 这样的方法并省略访问修饰符

是

是

否

否

避免这样做! 始终指定访问修饰符!!

公共

是

是

是

是

私有

是

否

否

否

受保护

是

是

是

否

良好的设计倾向于采用将所有内容设为私有,除非你明确希望外部类能够交互的字段和方法的方法。

作为一般规则,类的字段应设置为 private,并根据具体情况授予其他访问级别。

对这些字段的访问应通过相应的 getter 和 setter 方法提供。

通常,getter 和 setter 方法是公共方法。

更多信息可通过下方链接获取

https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

2.6. 设计活动:为 ABC 有限公司进行电子商务解决方案(在线店面)的案例研究

回顾下面的案例研究,然后

  • 考虑软件解决方案必须支持的各种流程和需求(示例可能包括客户注册、结账、提交付款、发送发票、履行订单、发货)

  • 注意名词和名词短语,然后识别哪些是类,哪些是字段

  • 注意动词和动词短语,然后为每个类识别可能的方法

2.6.1. 案例研究 - ABC 有限公司的电子商务解决方案(在线店面)

您需要为零售公司 ABC Ltd. 设计一个电子商务解决方案(在线店面)。

此设计必须采用 UML 类图的形式。高层需求已在下方提供。

ABC 将利用该解决方案来推广和销售其商品目录中列出的数千种产品。尽管 ABC 预计在不久的将来会增加其他产品,但目前该目录包括书籍、DVD、音乐 CD、服装、消费电子产品、美容产品、厨房用品、珠宝、手表、园艺用品和玩具。

潜在客户必须能够访问在线店面以:

  • 搜索或浏览 ABC 的产品目录

  • 查看产品详情(包括描述、价格、客户评分和评论等)

  • 管理他们的购物车(将商品添加到购物车、移除商品等)

此外,已注册客户必须能够登录、管理其用户账户、结账/下单,并提交对先前购买商品的评论。要注册,客户用户必须完成并提交在线注册表单,向 ABC 提供其电子邮件地址、密码,以及以下各项中的一项或多项:电话号码、送货地址、账单地址和付款详情。

ABC 的客户服务、订单履行以及其他员工用户也必须能够使用该系统来支持业务运营。

2.7. 识别关系、层次结构以及复用机会

设计软件产品的下一步是识别超类、子类以及类之间的关系。

2.7.1. 泛化 / 继承

回想一下,可能存在“是一个”关系,也称为泛化/继承关系,其中子类(或派生类)从某个父类(基类)“继承”公共属性(字段)和行为(方法)。

识别这些关系以及相应的子类与超类,通常是迈向最终设计的良好早期步骤。

2.7.2. 实现

可能存在实现关系,其中 接口 在概念上定义了一组属性(字段)和行为(方法)。然后,实现该接口的类通过实现这些属性(字段)和行为(方法)来“实现”它。

在使用数据结构时,您的设计中很可能需要包含一个或多个实现关系。如果没有,则可能需要重新审视您的类并添加适当的接口。

2.7.3. 聚合/组合

可能存在“有一个”关系,也称为聚合关系,用于描述实体(类)之间的整体 - 部分或部分属于整体的关系。

2.7.4. 其他关系与设计考量

其他关系标签如 关联 、 依赖 和 多重性 也存在。UML 类设计文档所需的细节很大程度上取决于您的软件开发上下文,有些需要充分利用所有适当的 UML 标注,而另一些可能只要求描绘最重要的设计元素。

如果对所需细节的级别有疑问,请随时提问并查阅整个模块、实验和项目中提供的示例里的 UML 类设计。

关于关系、层次结构和复用所需的大部分内容已在 多态 模块中涵盖。此外,您可以下载 UML Diagram key 以浏览 UML 图。您应复习这些内容,然后继续下面的活动。

2.8. 设计活动:确定类之间的关系

回顾可从 ABC Ltd. 案例研究——电子商务解决方案(在线店面)中提取的名词、名词短语和概念列表。

Nouns and Noun Phrases

商品

商品目录

书籍

DVD

服装

消费电子产品

美容用品

厨房用品

珠宝

手表

玩具

顾客

评论

评分

购物车

账户

订单

用户

电子邮件地址

密码

送货地址

账单地址

支付详情

员工用户

Concepts

用户账户

购物车

结账

支付、支付系统、支付选项

订单履行

综上所述,我们可以确定以下初始候选类列表。

Possible Classes

产品目录

产品

图书

DVD

服装

消费电子产品

美容用品

厨房用品

珠宝

手表

玩具

评分

评审

订单

支付

用户

顾客

员工

注意:可能还有其他选项,例如:

ShoppingCart 可以是一个类,也可以仅仅是 Product 的集合

地址可以是一个包含街道、城市、国家等字段的类,或者仅仅是一个字符串。如果地址是一个类,那么字段 billingAddress 和 shippingAddress 的类型就可以是地址。

2.8.1. 超类与子类

现在我们有了候选类列表,可以识别超类和子类,请记住我们正在寻找类对之间的“是一个”关系。

其中一些应该希望会立即变得显而易见。在考虑产品时,我们可能会识别出可能的超类/子类对:

注意:

  • 图书“是一种”商品

  • DVD“是一种”商品

  • 服装、消费电子产品、美容用品、厨房用品、珠宝、手表和玩具也是如此!

我们有了第一个超类与子类层次结构!

此外

  • 客户“是一种”用户

  • 员工“是一种”用户

请记住,所设想的软件系统需要管理每个产品共有的信息,以及每种产品类型独有的信息和行为。

例如,价格和描述是所有产品(无论是服装、书籍还是 DVD)共同关注的属性。

另一方面,对于像服装这样的产品,系统还需要管理独特的服装特定属性,如尺码、材质类型和颜色。对于像书籍这样的产品,系统需要管理独特的书籍特定属性,如 ISBN 和作者。

一种良好的设计方法是将所有类共有的属性和行为包含在各自的超类或父类(在本例中为 Product)中,而将独特的属性和行为作为每个子类或子类的一部分。将这些内容绘制成图表有助于组织思路。

2.8.2. 关系与数据结构

进一步检查这些关系可能有助于您确定设计是否需要一个或多个数据结构,或者优化您的方法。

请特别注意聚合、组合和多重性。例如,一个类可能包含另一个类的多个实例, ProductCatalog 就是一个例子,它会包含 Product 的多个实例。在设计中,这可以通过多个字段或通过一个表示产品集合的单个字段来实现。一旦认识到这种需求,您就需要决定哪种数据结构最合适。

对于其他关系,请思考概念、动词和动词短语,以及软件将支持的过程。反思这些内容有助于完善你的设计文档。

我们已重述 ABC 有限公司案例研究(电子商务解决方案,即在线店面)中的概念、动词和动词短语,供您审阅。

Concepts

用户账户

购物车

结账

支付、支付系统、支付选项

订单履行

Verb and Verb Phrases

搜索或浏览器

管理(购物车)

添加和移除(商品)

注册(客户账户)

下单(订单)

提交(评论)

支持(员工)

以批判的眼光审视你的设计,问自己:“我的设计能否支持这一概念、流程或操作?”如果不能,需要做出哪些更改来完善你的设计?

2.9. 检查点 2

2.10. 设计模式与 MVC 简介

2.10.1. 模式

利用模式(即针对常见且经过充分研究的问题的可重复最佳实践解决方案)这一理念,最早由 Christopher Alexander、Sara Ishikawa、Murray Silverstein、Max Jacobson、Ingrid Fiksdahl-King 和 Shlomo Angel 在 1977 年的著作 A Pattern Language: Towns, Buildings, Construction 中于建筑学领域提出。

在本书中,作者传达了以下关于利用模式潜在益处的观点:

“每个模式描述了在我们的环境中反复出现的问题,然后描述了该问题解决方案的核心,使得你可以使用这个解决方案一百万次而每次都不以相同的方式实现它”

-A Pattern Language - Towns, Buildings, Construction,第 8 页

2.10.2. 设计模式

软件工程界受这些作者以及利用先前经验解决常见问题的潜在益处所启发,选择通过创建和使用设计模式来采用类似的方法。

在软件工程中,设计模式是软件设计中常见问题的一种通用可复用解决方案。设计模式不是可以直接转换为代码的成品设计。它是一种描述或模板,用于说明如何在许多不同情况下解决问题。

设计模式为软件开发人员在软件设计与开发过程中遇到的问题提供了最佳实践解决方案。

需要注意的是,这些设计模式是经过一段时间,通过试错以及众多开发者的宝贵经验逐步演化而来的。理解并恰当使用设计模式可以加快开发进程,帮助开发者避免常见陷阱,并总体上助力软件开发者学习和实践优秀的软件设计,而无需亲身经历前人所遭遇的失败与试错过程。

模型 - 视图 - 控制器和观察者设计模式都常用。Java 最初为此模型提供了 Observer 接口和 Observable 类,但由于它们不适合处理多个同时执行的线程,现已弃用。本页讨论 Observer 和 Observable——虽然该设计模式仍然成立,但这些类已弃用,在汉诺塔项目中,我们现在使用自己的 Model 和 View 类来替代它们。

2.11. 互动:MVC 与观察者视频

注意:本视频中的项目是汉诺塔项目的变体。

2.12. MVC 示例 AddressBook

考虑一个简单的移动地址簿应用程序的设计,该应用用于管理个人的联系人集合。构建此类应用程序需要编写负责以下任务的代码:

管理和维护与每个联系人相关的各种数据项,包括其名字、姓氏和电话号码

因此,我们可以利用从过往经验中获得的见解和专业知识,并采用经过验证的设计。对于需要数据逻辑、处理逻辑和表示逻辑的应用程序,一种经过验证的设计是 MVC(模型–视图–控制器)设计模式。

花点时间思考一下 MVC(模型–视图–控制器)设计模式和 AddressBook 应用程序,并考虑 AddressBook 应用程序的设计。

_images/ExMVCAddressBook.png

Try It Yourself

下载并在 Eclipse 中自行运行和探索视频中的对应项目。示例项目需要 CS2-Support 项目。它也用于你的课程项目中。要下载 CS2-Support,你必须先完成第一个实验的配置步骤。然后,你可以通过 Eclipse 使用蓝色向下箭头图标,或使用项目菜单并选择“下载作业..."来下载它。

2.13. 设计评审:案例研究 - 为 ABC 有限公司提供的电子商务解决方案(在线店面)

回想一下我们在“软件设计入门视频”中讨论的生成正确设计的若干步骤。此时,您应当回顾并反思为 ABC Ltd. 电子商务解决方案(在线店面)起草的设计,然后思考自上一版本以来所学到的内容。

在审查设计时,您应考虑 ABC Ltd. 的电子商务解决方案(在线店面)是否需要一个或多个数据结构来管理系统所使用的数据/对象,以及该设计是否受益于 MVC 或观察者等设计模式的应用。

2.13.1. 数据结构

一旦确定某个设计需要一个或多个数据结构,设计者就必须评估他们所知悉的每一个数据结构。此外,设计者还必须考虑应用程序的需求以及各种数据结构的特性和操作,以确定任何特定特性或操作是否对该应用程序有用或必要。

关于 ABC 有限公司的电子商务解决方案(在线店面),设计显然应至少包含一种数据结构。产品目录、支付、订单、购物车和用户账户等概念与名词,都表明系统中需要管理的可能对象分组或集合。

考虑各种数据结构,你会为每种情况选择哪一种,为什么?

例如,对于购物车而言,使用包还是栈更合理?我们知道,购物车应允许随时添加和移除元素(商品或物品),且不对可添加或移除的元素施加任何限制。栈会对这类购物车操作施加限制,却未带来显著优势,因此与包相比,栈并不适用。

对于产品目录,使用包、列表、队列还是其他数据结构最为合理?同样,请始终为你的选择提供理由。

如果您不确定如何确定最合适的一个,请重新审视您的软件需求,或许可以这样做。

例如,系统是否应该包含一个用于产品目录的排序功能?答案很可能是肯定的。

这可能是系统的需求之一。

如果是这样,那么作为设计者的您,应该考虑哪些数据结构支持排序而哪些不支持,这将有助于缩小产品目录实现的最合适选项范围。

依次考虑每个需求和集合,然后细化你的设计,以包含所选的数据结构和支持类(接口等)。

2.13.2. 设计模式

希望您的设计进展顺利,现在是考虑使用一个或多个设计模式的合适时机。虽然在后续的软件工程课程中这将是一个更深入研究的重点,但在当前阶段我们只需做出相对简单的决策。目前,针对 ABC 有限公司的电子商务解决方案(在线店面),我们主要关注回答以下问题:

  • 设计是否应使用 MVC 设计模式?

  • 设计是否应使用观察者设计模式?

  • 设计是否应同时使用 MVC 和观察者设计模式?

基于我们对 MVC 的理解以及 ABC Ltd. 电子商务解决方案(在线店面)的需求,显然我们提出的系统

  • 需要一个图形用户界面(视图)

  • 拥有需要管理的数据和业务逻辑(模型),以及

  • 拥有需要处理的加工过程,其中一部分是对用户交互的响应(控制器)

我们应用程序的需求模式与 MVC 设计模式所提供的功能相匹配,因此该设计非常适用。

目前我们不会深入探讨观察者模式,尽管它在此应用中可能有用,但也会(对此应用而言)增加不必要的复杂性。当我们拥有状态持续变化的对象(可观察对象),而另一个对象(观察者)需要获知这些变化时,我们会使用观察者模式。

关于 ABC 有限公司的电子商务解决方案(在线店面),大多数对象的状态主要在用户直接与其交互时受到影响。这些对象不会自行改变状态,目前也不会被视图、控制器或模型以外的任何类提示去改变状态。因此,它们已经协同工作以更新那些可被视为观察者的相关类(例如视图或图形用户界面类)。

关于此案例,应使用 MVC 设计模式,而观察者(目前不应使用)。

您应审查当前设计并修改它以包含这些更新。

2.14. 设计评审:案例研究 - 自动售货机

你受雇为自动售货机应用制作高层软件设计。

此设计必须采用 UML 类图的形式。

您的客户希望您以实际自动售货机的优秀案例为灵感来进行软件设计。

关于其他需求,您的客户指出实体自动售货机在形式、行为和特性上应与下图所示机器类似:

Overall view of an internet-enabled vending machine
Overall view of the customer interface, showing the keypad for selecting the item, as well as two payment interfaces, one for card swipe or cash, and one for payment with a mobile device.
Closeup view of the mobile device payment  interface, showing the flavors of payment systems supported (Apple Pay, Android Pay, Samsung Pay), as well as the credit card types supported.

考虑支持自动售货机所需的软件需求,然后

  • 考虑软件解决方案必须支持的各种过程,并记录主要过程及部分主要需求

  • 回顾你的笔记,识别名词和名词短语,然后思考哪些是类、哪些是字段

  • 回顾你的笔记,识别动词和动词短语,然后为每个类确定可能的方法

   «  1. 伦理   ::   目录   ::   3. 实验 6 数组栈  »

关闭窗口