面向对象分析与设计,在软件工程中越来越重要了。可惜很多大学的计算机都没有这门课。大多人读书时候,入门学了
C++等面向对象语言,也只是停留在语言层面,对于面相对象的精髓一知半解。在实际项目中,分析建模也是完全凭感觉,
即使错了,也不明白为什么?这本书是 面向对象分析与设计 入门的捷径。它延续Head First 系列的风格,轻松易懂,在
不知不觉中,你就掌握了原理。在此强烈推荐!
一、良好的应用程序的基石
伟大软件的简易三步骤:
1.确认你的软件做客户要它完成的事。
2.运用基本的OO原则来增加软件的灵活性。
3.努力实现可维护、可重用的设计。
分析:为正在试图解决的问题用文字描述清楚,确保你的设计与应用程序想实现的功能一致
对象类型不匹配的原因:
1.对象应该做其名称所指之事。
2.每个对象应该代表单一概念。
3.未使用的对象是无用的赠品
封装让你将应用程序分成一组一组合乎逻辑的部件
看到重复的代码,就是该进行封装的时候了
委托将处理特定工作的责任转交给另一个对象
一旦完成基本功能,就重新细化你的设计,让它更灵活
隔离出经常变化的部分
二、收集需求
需求:It's a specific thing your system has to do a work correctly.
用例:A use case describes what your system does to accomplish a particular customer goal.
用例有三个基本部分:
清楚的价值,
起点和终点
外部启动者
按照用例检查需求,确保用例涵盖了系统必须做的每一件事
需求是系统为了正确运作所必须要做的事
最初的需求通常来自客户
三、需求变更
客户永远是对的
需求总是在变,然而,假如有良好的用例,你通常能快速地改变你的软件以适应这些新需求
替换路径:包含在用例中的一个或多个步骤,这些步骤是可选的或提供替换性的方式
场景:从第一步到最后一步通过用例的完整路径
任何时候你改变了用例,你就必须回头检查你的需求
有时候,需求的变更揭露出关于系统你所不知道的问题
变更是经常的,随着你每次的实现,系统总是随之改善
将变化之物封装起来
四、分析
分析帮助你确保系统运作在真实世界的情境里
以对客户、老板及自己合理的方式编写你的用例
分析及用例让你给客户、经理和其他开发者展示系统在真实世界的情境里如何运作
文本分析(textual analysis):查看用例里的名词(与动词)以整理出类和方法的动作
好的用例以容易理解的语言,清楚且准确地理解系统在做什么
有了良好、完整的用例,文本分析是整理出系统所需类的简单而快速的方式
系统外的名称不会转变成类
每个用例应该只聚焦于一个客户目标。假如有多个目标,你就需要编写多个用例
五、良好的设计=灵活的软件
抽象类是实际的实现类的占位符(placeholder)
抽象类定义行为,而子类实现该行为
两个或更多的地方找到共同行为时,小心地将该行为抽取到一个类里,然后以此共同类重用这项行为
对接口编程,而不是对实现,让你的软件更容易被扩展
通过对接口编程,你的程序代码将使用该接口的所有子类,甚至是还没被创建的那些
每个类只有一个改变的理由。单一职责
编码一次,查看多次
设计是反复迭代的。你必须愿意改变自己的设计以及你从其他程序设计大师那里继承的设计
A cohesive class does one thing really well and does not try to do or be something else.
每个类都应该试图确保这件事的发生只有一个理由,这件事代表许多设计不良的软件片段之死
伟大的软件通常就是“够好”的软件
确认客户高兴,确认你的设计具有灵活性,可以继续往前走了
六、解决大问题
用解决小问题的相同方式解决大问题
看待大问题的最佳方式就是化整为零,将它视为许多单独的功能片段
你可以将那些片段的每一个创建为要解决的单独的问题,并且运用到你已经知道的每一件事
功能:功能只是关于系统需要做的某件事的高级描述
只要可以,就尽量把细节往后拖延,需要有关整体轮廓的观点
领域分析让你检查你的设计,并且是以客户所用的语言
领域分析:识别、收集、组织以及表示领域相关信息的流程
领域分析帮你避免构建不属于你的责任范围内的系统部分
七、架构
Architecture is your design structure, and highlights the most important parts of your app,
and the relationships between those parts.
架构是系统的组织结构,包含分解开来的各个部件、它们的连通性、交互机制以及你在系统设计中使用的指导原则与决策
应用程序中真正重要的事情是架构上重要的事,你应该先把焦点置于其上
架构三问:
它是系统本质的一部分吗?
这是什么意思?
我到底该如何做?
一次把焦点放在一个功能上,减少项目的风险
不要为无助于减少风险的功能分心
越多次序,越少混乱
尽可能在现有基础上构建
有时候,编写伟大程序代码的最佳方式,是在允许的情况下将程序代码的编写往后顺延
询问客户,共同性分析,实现计划
八、设计原则
模拟是避免做傻事的最佳方式
开闭原则Open-Closed Principle :类应该允许为扩展而开放,禁止为修改而关闭
不重复 Don't Repeat Yourself
单一职责 Single Responsibility 系统里的每一个对象应该具有单一职责,所有对象的服务都应该聚焦在实现该职责上
(可以用一个简单的方法检验类的方法是否合理 The class do itself)
里氏替换原则 Liskov Substitution 子类型必须能够被替换成它的父类型
将功能性委托给其他类
假如你需要使用另一个类的功能性,但不想改变该功能性,可以考虑以委托代替继承
使用组合将来自其他多个类的行为集合起来,在运行时切换该行为
在组合中,由其他行为所组成的对象拥有那些行为。当对象被摧毁时,其所有行为也被摧毁。组合中的行为不存在于组合本身以外
聚合:当一个类被作用另一个类的一部分时,但仍然可以存在于该类之外
使用组合或聚合:想使用其行为的对象存在于使用其行为的对象之外吗?
九、迭代与测试
伟大软件的编写是迭代进行的
先针对整体轮廓操作,接着迭代应用程序的每个片段,直到完成
功能驱动开发:挑出应用程序的特定功能,并且规划、分析及开发该功能,直到完成
用例驱动开发:挑出通过用例的场景,并且编写程序代码以支持通过该用例的完整场景
设计决策总是一种取舍
每当你迭代时,重新评估你的设计决策,假如它对你的设计合理,就别害怕改变
契约式编程:假设协议双方了解什么动作会产生什么行为,并且遵守该契约
防御式编程:寻找可能出错的地方,提前避免