9.2. 软件设计与 MVC¶
9.2.1. 目标¶
完成本模块后,学生将能够:
识别功能需求与非功能需求
从文档化的需求中识别类、字段、方法以及类之间的关系
描述使用设计模式的目的与益处
解释并运用 MVC 与观察者设计模式
应用并展示良好的设计实践
使用 UML 类图生成软件系统的设计
9.2.2. 交互式:软件设计简介 [9:30]¶
Follow Along and Engage
下载与视频对应的幻灯片。观看视频时做笔记,亲自练习绘制图表!
9.2.3. 功能需求与非功能需求¶
如果您被要求设计某种软件产品,并且您发现自己只拥有一个描述所提议软件产品的高级概述,那么通过 识别 并 记录 潜在的函数和非函数需求可能是一个好主意。
这有助于您更好地构想软件产品、软件可能支持的不同用户和流程,以及软件内预期的各种操作和功能。至少,此练习将为您提供与利益相关者和用户进行后续讨论的起点,有望引导至更详细的需求收集。
注意,功能需求与非功能需求将在其他课程中更详细地探讨。
目前,对这些要求的总体理解就足够了。
回顾下面提供的功能需求和非功能需求的描述与示例。
9.2.3.1. 功能需求¶
这些是规定给定系统或软件产品 应该 做什么的要求。功能需求通常以“系统应当做”<需求>*的形式表述。
关于 电子商务解决方案(在线商店) 的某些功能需求示例可能包括:
系统应允许用户 ________
根据特定搜索条件(例如名称、描述或产品标识符)搜索产品
查看产品详情
将产品添加到购物车
从购物车中移除产品
系统应允许已注册的顾客________
下订单
提交付款
查看订单详情
登录账户(log in)
管理账户资料
更改密码
关于图书馆管理系统,功能需求的一些例子可能包括:
系统应允许读者(即使用图书馆的人)________
根据特定搜索条件(例如书名、作者或 ISBN)搜索一本书
查看图书详情
预订图书
借阅图书
归还图书
9.2.3.2. 非功能性需求¶
功能需求规定了系统 应该做什么,而非功能需求规定了它 应该如何做,即给定的系统或软件产品应如何执行其各种功能。 非功能需求通常规定质量属性,包括与可用性、性能、可靠性、安全性、可维护性等相关的属性。
关于电子商务解决方案(在线商店)的示例,一些非功能性需求可能包括:
系统应 ________
在 2018 年之后发布的所有浏览器和浏览器版本上正确运行
利用响应式设计
在 2 秒内完成(并提供结果)用户发起的搜索
能够每秒处理 1000 万用户,且性能/用户响应时间无降级
仅接受长度至少为八 (8) 个字符且包含 - 至少一个大写字母、一个特殊字符和一个数字的账户密码
关于 图书馆管理系统,一些非功能性要求的示例可能包括:
系统应 ________
在 4 秒的最大响应时间内完成(并确认成功或失败)用户发起的请求
支持对至少 100,000 本图书馆藏书及相关图书馆媒体的跟踪与管理
支持每分钟高达 5000 个读者请求
易于具备基本计算机素养(浏览器、网页浏览、文字处理、搜索引擎等)的人员使用
包含所有相关操作的验证检查、用户确认提示及其他提示,以帮助人们避免犯错
9.2.4. 检查点 1¶
9.2.5. 识别类、字段和方法¶
使用 UML 类图设计软件产品的第一步是审查已记录的需求,目标是识别系统的类、字段和方法。第一步是审查软件需求并记录所有的名词、动词、过程和概念。
回顾一下,类是对象的蓝图或规范。它们通常是感兴趣的实体,具有属性(数据/信息片段,通常称为字段)和行为(方法),这些对于软件按预期运行是必需的。
9.2.5.1. 识别类与字段¶
类与字段源自我们软件需求文档中发现的名词和名词短语。有些也可以通过考虑软件产品将如何被使用、软件旨在支持的过程以及软件的用户来找到。
名词和名词短语要么指代系统感兴趣的实体(事物),要么指代与这些实体关联的数据/信息片段。
因此,名词和名词短语是类的良好候选者,或是类的字段。
9.2.5.2. 区分哪些名词是类,哪些是字段¶
一旦你记录了所有的名词,接下来你需要确定哪些是类,哪些是字段。 以下规则将帮助你区分类与字段。
指代具有多个感兴趣属性(属性)的实体(事物)的名词和名词短语最可能是类
指代单个属性或数据项的名词和名词短语最可能是某个类的字段
9.2.5.3. 数据结构¶
确定是否有任何类需要与另一个类的 1 个实例或许多实例进行交互(或管理)。
如果需要许多实例,则考虑是否可以用数据结构来管理这些实例。下一步将评估并选择一种或多种数据结构,以提供符合预期系统需求的操作和功能。
9.2.5.4. 识别类的方法¶
方法是从审查软件需求文档并考虑软件旨在支持的过程时发现的动词和动词短语派生的。
动词和动词短语暗示了类的职责,这将有助于您推导方法。
记住每个类应遵循单一清晰的概念,即一组相关的职责。此外,每个方法应很好地执行或完成一项任务。
将动词和动词短语归类到应该负责执行这些操作或任务的类下。这些很可能是该类的方法。记住,一个类通常应该负责管理自身及其字段。
9.2.5.5. 访问修饰符与类、字段及方法的可见性¶
访问修饰符允许开发人员指定其他类是否可以使用特定字段或调用给定类的特定方法。
新开发者经常忘记为类、字段和方法指定访问修饰符。
这是一种不良习惯,应避免,因为省略访问修饰符可能导致某些意外行为,破坏封装性,并可能允许外部类以非预期的方式访问字段和方法。
在绘制软件设计方案以及开发软件解决方案时,您始终应为所有类、字段和方法指定访问修饰符,无论是在描绘软件设计还是在开发软件解决方案时。
访问修饰符 / 可见性修饰符 |
同一类 |
同一包 |
包外 |
世界 |
备注 |
|---|---|---|---|---|---|
未设置 例如,一些开发人员会声明一个像 |
是 |
是 |
否 |
否 |
避免这样做! 始终指定访问修饰符!! |
公共 |
是 |
是 |
是 |
是 |
|
私有的 |
是 |
否 |
否 |
否 |
|
受保护的 |
是 |
是 |
是 |
否 |
良好的设计倾向于采用将一切设为私有,除非您明确希望外部类与之交互的字段和方法。
作为一般规则,您类的字段应设置为私有,并根据具体情况授予其他级别的访问权限。
对这些字段的访问应通过相应的 getter 和 setter 方法提供。
通常,getter 和 setter 方法是公共方法。
更多信息可通过下方链接获取
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
9.2.6. 设计活动:案例研究 ABC Ltd 电子商务解决方案(在线商店)¶
回顾下面的案例研究,然后
考虑软件解决方案必须支持的各种过程和需求(示例可能包括:客户注册、结账、提交付款、发送发票、履行订单、发货)
注意名词和名词短语,然后确定哪些是类,哪些是字段
注意动词和动词短语,然后确定每个类可能的
9.2.6.1. 案例研究 - ABC Ltd 的电子商务解决方案(在线商店)¶
你需要为零售公司 ABC Ltd 的电子商务解决方案(在线商店)设计一个设计方案。
此设计必须采用 UML 类图的形式。高级需求已在下方提供。
ABC 将使用此解决方案来推广和销售 ABC 产品目录中列出的数千种产品。虽然 ABC 预计将在不久的将来添加其他产品,但当前目录包括书籍、DVD、音乐 CD、服装、消费电子、美容产品、厨房用品、珠宝、手表、花园用品和玩具。
潜在客户必须能够访问在线商店以:
搜索或浏览 ABC 的产品目录
查看产品详情(包括描述、价格、客户评分和评论等)
管理购物车(将产品添加到购物车、移除产品等)
此外,已注册的客户必须能够登录、管理其用户账户、结账/下单,并提交对先前购买物品的评论。要注册客户,用户必须完成并提交在线注册表,向 ABC 提供其电子邮件地址、密码以及以下各项的一个或多个:电话号码、送货地址、账单地址和付款详情。
ABC 的客户服务、订单履行以及其他员工用户也必须能够使用该系统以支持业务运营。
9.2.7. 识别关系、层次结构以及可复用机会¶
设计软件产品的下一步是识别超类、子类以及类之间的关系。
9.2.7.1. 泛化 / 继承¶
回忆一下,可能存在“是一种”关系,也称为泛化/继承关系,在这种关系中,子类(或派生类)从某个父类(超类)“继承”共同的属性(字段)和行为(方法)。
识别这些关系以及相应的子类与父类,通常是迈向最终设计的良好早期步骤。
9.2.7.2. 实现¶
可能存在实现关系,其中 接口 概念上定义了一组属性(字段)和行为(方法)。然后实现该接口的类通过实现属性(字段)和行为(方法)来“实现”它。
在使用数据结构时,您的设计中可能应该包含一个或多个实现关系。如果没有,您可能需要重新审视您的类并添加适当的接口。
9.2.7.3. 聚合 / 组合¶
可能存在“有”关系,也称为聚合关系,它描绘了实体(类)之间的部分 - 整体或部分 - 部分关系。
9.2.7.4. 其他关系与设计考虑¶
还存在其他关系标签,如 关联、依赖 和 多重性。你的 UML 类设计文档所需的细节在很大程度上取决于你的软件开发环境,有些需要完全使用所有适当的 UML 注释,而有些可能只需要描绘最重要的设计元素。
如果对所需的详细程度有疑问,请随时提问,并查阅本模块、实验室和项目示例中提供的 UML 类设计。
之前关于关系、层次结构和复用所需的大部分知识已在 关于多态性的更多内容 模块中涵盖。此外,您可以下载 UML Diagram key 以导航 UML 图。您应复习这些内容,然后继续下面的活动。
9.2.8. 设计活动:确定类之间的关系¶
复习从案例研究 - ABC Ltd 电子商务解决方案(在线商店)中提取的名词、名词短语和概念列表。
产品 |
产品目录 |
书籍 |
DVD |
服装 |
消费类电子产品 |
美容用品 |
厨房用品 |
珠宝 |
手表 |
玩具 |
客户 |
评论 |
评分 |
购物车 |
账户 |
订单 |
用户 |
电子邮件地址 |
密码 |
收货地址 |
账单地址 |
支付详情 |
员工用户 |
用户账户 |
购物车 |
结账 |
支付、支付系统、支付选项 |
订单履行 |
考虑到上述内容,我们可以确定以下各项作为可能的类的初始列表。
产品目录 |
产品 |
书籍 |
DVD |
服装 |
消费电子 |
美容用品 |
厨房用品 |
珠宝 |
手表 |
玩具 |
评分 |
评论 |
订单 |
付款 |
|||||||
用户 |
客户 |
员工 |
注意:可能还有其他选项,例如:
ShoppingCart 可以是一个类或仅仅是 Products 的集合
地址可以是一个包含街道、城市、国家等字段的类,或者仅仅是一个单一的 String。如果 Address 是一个类,那么字段 billingAddress 和 shippingAddress 的类型就可以是 Address。
9.2.8.1. 超类与子类¶
现在我们已经有了候选类列表,可以识别超类和子类,回想一下我们在寻找类对之间的“是 - 一种”关系。
有些应该希望立即变得明显。当考虑 Products 时,我们可能识别出可能的超类/子类对:
注意:
Book“是”Product
DVD“是”Product
服装(Apparel)、消费电子(Consumer Electronics)、美妆(Beauty item)、厨房用品(Kitchen item)、珠宝(Jewelry)、手表(Watch)以及玩具(Toys)也是如此!
我们有了第一个超类和子类层次结构!
此外
Customer“是”User
Employee“是”User
请记住,设想的软件系统需要管理每个 Product 共有的信息片段,以及每种类型 Product 独有的任何信息和行为。
例如,价格和描述将是所有产品(无论是服装、书籍还是 DVD)都感兴趣的属性。
另一方面,对于 Apparel 这类产品,系统还需要管理 Apparel 特有的唯一属性,如尺寸、材料类型和颜色。对于 Book 这类产品,系统则需要管理 Book 特有的唯一属性,如 ISBN 和作者。
一种好的设计方法是将所有共有的属性和行为包含在各自的超类或父类中,在本例中为 Product 类。然后将独特的属性和行为作为每个子类或子类的组成部分包含进去。在图中绘制出来有助于组织你的想法。
9.2.8.2. 关系与数据结构¶
进一步检查关系可能有助于您确定设计是否需要一个或多个数据结构,或改进您的方法。
特别注意聚合、组合和多重性。例如,一个类可能包含另一个类的多个实例,ProductCatalog 会包含多个 Product 的实例。在此设计中,可以通过多个字段或通过代表 Products 集合的单个字段来容纳这一点。一旦认识到这种需求,就需要决定哪种数据结构最合适。
对于其他关系,请思考概念、动词和动词短语,以及软件将支持的过程。反思这些内容将有助于您完善设计文档。
我们已重述了案例研究——ABC Ltd 电子商务解决方案(在线商店)的概念、动词和动词短语,供您审阅。
用户账户 |
购物车 |
结账 |
支付、支付系统、支付选项 |
订单履行 |
搜索或浏览器 |
管理(购物车) |
添加和移除(产品) |
注册(客户账户) |
下单 |
提交(评论) |
支持(员工) |
用批判的眼光审视你的设计,问自己:“我的设计能否支持这个概念、过程或动作?”如果不能,需要做出哪些修改来完善你的设计?
9.2.9. 检查点 2¶
9.2.10. 设计模式与 MVC 简介¶
9.2.10.1. 模式¶
利用模式(patterns)这一理念,即针对常见且已充分探索的问题采用可重复的最佳实践解决方案,最早由 Christopher Alexander、Sara Ishikawa、Murray Silverstein、Max Jacobson、Ingrid Fiksdahl-King 和 Shlomo Angel 在其 1977 年出版的建筑学著作 A Pattern Language: Towns, Buildings, Construction 中提出。
在本书中,作者传达了以下关于利用模式潜在益处的思考:
“每种模式都描述了一种在我们环境中反复出现的问题,并描述了该问题解决方案的核心,使得你可以无数次地应用这一解决方案,而无需以完全相同的方式重复操作”
模式语言——城镇、建筑与建造,第 8 页
9.2.10.2. 设计模式¶
软件工程界受这些作者启发,并认识到利用先前经验解决常见问题所带来的潜在益处,选择通过创建和使用设计模式(Design Patterns)采用类似的方法。
"在软件工程领域,设计模式是针对软件设计中常见问题的通用可复用解决方案。设计模式并非可以直接转换为代码的成品设计。它是对如何解决某一问题的描述或模板,可在多种不同情境中加以应用。"
设计模式为软件开发者提供了在软件设计与开发过程中遇到问题的最佳实践解决方案。
值得注意的是,这些设计模式是在一段时间内通过试错和众多开发者的艰辛经验演变而来的。理解并恰当地使用设计模式可以加快开发过程,帮助开发者避免常见陷阱,并且总体上帮助软件开发者学习和实践良好的软件设计,而无需经历前辈所遭遇的失败和试错。
模型 - 视图 - 控制器(Model-View-Controller)和观察者(Observer)设计模式均被广泛使用。Java 最初为此模型提供了观察者(Observer)接口和可观察(Observable)类,但由于它们不适合处理多个同时执行的线程,现已弃用。本页面讨论观察者(Observer)和可观察(Observable)——尽管该设计模式依然有效,但这些类已被弃用;在汉诺塔(Tower of Hanoi)项目中,我们现在使用自己的模型(Model)和视图(View)类来替代它们。
9.2.11. 交互式:MVC 和观察者视频 [11:00]¶
注意:本视频中的项目 3 是汉诺塔项目的变体。
9.2.12. MVC 示例 AddressBook¶
考虑一个用于管理个人联系人集合的简单移动 AddressBook 应用程序的设计。构建此类应用程序需要编写负责以下内容的代码:
管理与维护与每个联系人关联的各种数据项,包括其姓、名和电话号码(s) 将数据项处理为有用信息,提供必要的用户功能,响应用户输入,并确保遵循应用程序的规则 向用户展示数据和信息,并提供设施使用户能够与所展示的数据和信息进行交互 这一系列职责在软件开发的数十年中,在许多其他应用领域得到了充分探索。
因此,我们可以利用从过去经验中获得的见解和专业知识,并采用经过验证的设计。一种适用于需要数据逻辑、处理逻辑和展示逻辑的应用程序的经过验证的设计是 MVC(模型 - 视图 - 控制器)设计模式。
花一点时间反思 MVC(模型 - 视图 - 控制器)设计模式与 AddressBook 应用程序,并考虑 AddressBook 应用程序的设计。
Try It Yourself
在 Eclipse 中,使用 Project > Download Assignment... 菜单命令下载名为 "ex09.02-AddressBookMVC" 的练习项目
如需回顾下载 Eclipse 项目的说明,请参见 01.02: Lab: LightBot for Beginners。
9.2.13. 设计评审:案例研究——ABC Ltd. 的电子商务解决方案(在线商店)。¶
回顾“软件设计简介视频”中,我们讨论了若干步骤以生成适当的设计。此时,您应回顾并反思为 ABC Ltd. 电子商务解决方案(在线商店)所草拟的设计,然后考虑自上次版本以来您学到了什么。
在审查您的设计时,您应考虑 ABC Ltd. 的电子商务解决方案(在线商店)是否需要一个或多个数据结构来管理系统使用的数据/对象,以及该设计是否会从应用设计模式(如 MVC 或 Observer)中受益。
9.2.13.1. 数据结构¶
一旦确定某个设计需要一种或多种数据结构,设计者就必须评估其接触过的每种数据结构。此外,设计者必须考虑应用程序的需求,以及各种数据结构的特性和操作,以确定任何特定特性或操作是否对给定应用程序有用或必要。
关于 ABC Ltd. 的电子商务解决方案(在线商店),应显而易见的是,设计实际上应至少包含一个数据结构。ProductCatalog、Payments、Orders、Shopping Cart 和 UserAccounts 的概念和名词都表明了需要由系统管理的对象的可能分组或集合。
考虑各种数据结构,你会为每种选择什么以及为什么?
例如,使用 Bag 还是 Stack 作为 ShoppingCart 是否更有意义?我们知道,Shopping Cart 应该允许添加和删除元素(Products 或 Items),而不对任何时间点可添加或删除的元素施加限制。Stack 为 ShoppingCart 操作添加了限制,却未带来任何显著益处,因为与 Bag 相比,这样的 Stack 并不合适。
那对于 ProductCatalog 而言,Bag、List、Queue 还是其他某种数据结构最为合适?再次强调,选择时总要有理由。
如果您不确定如何确定最合适的需求,请重新审视您的软件需求,那么也许。
例如,系统是否应该包含产品目录的排序功能?答案很可能是肯定的。
这很可能是该系统的要求之一。
如果是这样,那么您(设计者)应考虑哪些数据结构支持排序,哪些不支持,这有助于缩小产品目录实现的最合适选项范围。
逐一考虑每个需求及集合,然后细化你的设计,以包含所选的数据结构(Data Structure(s))和支持类(Interfaces 等)。
9.2.13.2. 设计模式¶
希望您的设计进展顺利,现在是考虑使用一个或多个设计模式的合适时机。虽然这将在后续的软件工程课程中进行更深入的研究,但在当前层次我们只需做出一个相对简单的决定。就目前而言,针对 ABC Ltd. 的电子商务解决方案(在线商店),我们主要关注回答以下问题:
设计是否应使用 MVC 设计模式?
设计是否应使用观察者设计模式?
设计是否应同时使用 MVC 和观察者设计模式?
基于我们对 MVC 的理解以及 ABC Ltd. 电子商务解决方案(在线商店)的需求,很明显我们提出的系统
需要一个 GUI(视图)
拥有用于管理的数据和业务逻辑(模型),以及
需要处理的程序,其中一部分是对用户交互的响应(控制器)
我们应用程序的需求模式与 MVC 设计模式所提供的相匹配,因此它非常适合此设计。
目前我们不会深入探讨观察者模式,虽然它在此应用中可能有用,但也为此应用增添了不必要的复杂性。 我们在拥有需要被另一个对象(观察者)通知其状态持续变化的对象(可观察对象)时使用观察者模式。
就 ABC Ltd. 的电子商务解决方案(在线商店)而言,当用户直接与其交互时,大多数对象的状态会受到主要影响。对象不会自行改变状态,并且目前除了 View、Controller 或 Model 之外的任何类都不会提示它们改变状态。因此,这些对象已经协同工作,以更新可被视为观察者(例如 View 或 GUI 类)的相关类。
关于本案例,应使用 MVC 设计模式,而不应使用观察者模式(暂时)。
您应当回顾您当前的设计,并对其进行修改以包含这些更新。
9.2.14. 设计评审:案例研究 - 自动售货机¶
您受雇为自动售货机应用程序制作高层软件设计。
此设计必须采用 UML 类图的形式。
您的客户希望您使用实际自动售货机的优秀示例作为软件设计的灵感。
关于其他要求,您的客户指出,实体自动售货机在形式、行为和功能方面将与下图所示的机器相似:
|
|
|
考虑支持自动售货机所需的软件需求,然后
考虑软件解决方案必须支持的各种过程,并记录主要过程和一些主要需求
回顾笔记,识别名词和名词短语,然后考虑哪些是类以及哪些是字段
回顾笔记,识别动词和动词短语,然后为每个类识别可能的方法
