《UML和模式应用》读书笔记

《UML和模式应用》读书笔记

这是一本介绍OOA和OOA的不错的入门书. 对于我来说, 以前对OOA/D都是一些大致的概念, 而至于到底应该怎么在实际开发中使用却不得其解, 在这本书中解答了我的很多OOA/D方面的疑惑(另外整本书翻译的也很到位, 阅读起来非常顺畅). 实战性也非常强, 作者通过两个非常容易理解的例子(POS机和类似大富翁游戏)贯穿了整本书. 一般的模式, 设计原则, 我想市面上的书应该不少了.但是这里介绍的通用职责分配软件模式或原则(GRASP)却比较少见到, 难道是作者独创?还是本人孤陋寡闻?
在我看来, 整本书中都在强调一个东西, 就是职责, 在实际开发设计中抓住了, 理解了, 掌握了这个东西, 大部分的应用架构也不会差到那里去, 作者所谓的设计模式, 不管是创建者, 信息专家, 低耦合, 高类聚, 控制器等等模式都是在围绕职责来展开阐述.这个也是这本书对我最重要的启发. 难道这就是所谓的RDD(职责驱动设计)?

在OO开发中, 至关重要的能力是熟练地为软件分配职责.
为什么, 因为分配职责是必须要执行的一项活动(无论是画UML还是进行程序设计, 都要为软件对象分配职责), 并且它对软件构件的健壮性, 可维护性和可重用性具有重要影响.
当然, OOA/D中还有其他重要的技能, 但强调职责分配是因为他是一项既难掌握(涉及到大量需要权衡和抉择的问题)又至关重要的技能. 在实际项目中, 开发人员可能没有机会进行其他的建模活动, 而只能完成仓促的编码, 即使是这样的情况下, 分配职责这项工作也是必不可少的.

分析(analysis)强调的是对问题和需求的调查研究, 而不是解决方案, 分析一次含义广泛, 最好加上限制, 如需求分析, 面向对象的分析.

设计(design)强调的是满足需求的概念上的解决方案(软件和硬件方面), 而不是实现.设计思想通常排斥底层或显而易见的细节. 设计最终可以实现, 而实现则表达了真实和完整的设计.

分析和设计可以概括为:做正确的事儿(分析)和正确的做事(设计)

面向对象的分析强调是在问题领域内发现和描述对象(或概念), 例如, 在航班信息系统中包含飞机, 航班, 和飞行员等概念.

面向对象的设计强调的是定义软件对象以及它们如何协作以实现需求. 例如软件对象plane可以由tailNumber属性和getFlightHistory方法.

人们将应用的情节和场景编写成用例, 用例不是面向对象的制品, 而只是对情节的记录, 对于投骨子游戏的用例可以概括为:游戏者请求投骨子, 系统展示结果:如果骨子的总点数为7, 则游戏者赢, 否则游戏者为输.

面向对象的分析关注从对象的角度创建领域描述. 面向对象分析需要鉴别重要的概念, 属性和关联. 面向对象的分析的结果可以表示为领域模型, 在领域模型中展示重要的领域概念或对象.

领域模型并不是对软件对象的描述, 它使真实世界中的概念和想象可视化, 因此, 它也可以称之为概念对象模型.

面向对象的设计关注对象的定义:他们的职责和协作.

领域模型表示的是真实世界中的类, 设计类图表示是软件类, 尽管设计类图不同于领域模型, 但是其中的某些类名和内容还是相似的, 从这一方面来讲, OO设计和语言能够缩小软件构件和我们所设想的领域模型之间的差距.

设计知识是极不寻常的且更为重要的技能, 他并不是通过学习UML表示法或者CASE就可以掌握的, 如果不具备良好的OO设计和编程能力, 那么即使使用UML, 只能画出拙劣的设计.

建模(构建UML草图...)的目的主要是为了理解, 而非文档.

不要为所有或者大多数软件设计建模或者应用UML, 可以将简单的设计问题推延到编程阶段, 在编程和测试过程中解决这些问题. 只需要对设计空间中不常见, 困难和棘手的一小部分问题建模和应用UML

不要单独建模, 而是多人在白板上建模, 同时要记住建模的目的是发现, 理解和共享大家的理解. 白板上的UML草图使用足够好的简单表示法, UML细节是否精准并不重要, 关键是建模者应该能够互相理解, 坚持使用简单, 常用的UML元素.所有的建模可能不是准确的, 最终的代码或设计会与模型有差异, 甚至有极大的差异, 只有测试过的代码才能证实真正的设计; 先前绘制的模型图都是不完整的, 最好只是将其视为一次探索.

所有的UP制品都是可选的, 除非他们能增加价值, 否则避免创建这些制品, 应该致力于早期的编程, 而非构建文档.

在早期的迭代中解决高风险和高价值的问题.

在迭代的初始阶段只需要确定这个项目是否值得认真研究, 而不是真正深入进行研究.

需求的分类(FURPS):
功能性:特性, 功能
可用性:人性化因素, 帮助, 文档
可靠性:故障频率, 可恢复性, 可预测性
性能:响应时间, 吞吐量, 准确性, 有效性, 资源利用率
可支持性:适应性, 可维护性, 国际化, 可配置型.

用例
用例初学者的常见错误是注重次要的UML用例图, 而非重要的用例文本.
参与者是某些具有行为的事物, 可以是人, 计算机系统或组织.
场景是参与者和系统之间的一系列特定的活动或交互, 场景是使用系统的一个特定情节或用例的一条执行路径.
用例就是一组相关的成功或失败场景集合, 用来描述参与者如何使用系统来实现目标.

用例的另一个价值是强调了用户的目标和观点, 我们会提出这样的问题:"谁使用系统, 他们使用的典型场景是什么, 他们的目的是什么", 这些问题更强调以客户为中心.

用例应该包含什么? 答案是用例应该包含满足所有涉众关注点的事物.

前置条件传达的是编写者认为应该引起读者警惕的那些值得注意的假设. 有些条件必须为真, 但是不值得编写处理, 比如"系统必须有电力供应".

扩展必须有两部分组成:条件和处理, 其原则是尽可能的用系统或参与者能够检测到的事物作为条件.
比如:
系统检测到与外部税务计算系统服务的通信故障
外部税务计算系统工作不正常
前一种风格更好, 因为这是系统能够检测到的条件, 而后者只是一种推断.

以本质风格编写用例, 摒弃用户界面并且关注参与者的意图.

用例名称应使用动词开头

对于每个目标的一个用例来说, 常见的例外是, 将分散的CRUD合并成一个CRUD用例, 并习惯的称之为管理X, 比如管理用户(高喊了编辑, 删除用户).

用例很少由单独的活动或步骤组成, 相反, 用例通常包含多个步骤. 用例建模的一个常见错误就是仅将一系列相关步骤中的一个步骤定义为用例.

用例图和用例关系在编写用例工作中是次要的, 用例是文本文档, 编写用例意味着编写文本.

领域建模
如果采用敏捷建模方法, 创建领域模型的目的是为了快速理解和沟通大致的关键概念, 完美不是目的.

如果我们认为某概念类X不是现实世界中的数字或文本, 那么X可能是概念类而不是属性.
例如Store应该是Sale的属性还是单独的概念类
在现实世界中, 商店不会被认为是数字或文本, 这一术语表示的是合法的实体, 组织和占据空间的事物, 因此Store应该是概念类.

关联(关系)的大部分将作为导航和可见性路径在软件中加以实现, 但是, 领域模型不是数据模型, 添加关联是为了突出我们对重要关系的大致理解, 而非记录对象或数据结构.

以"类名-动词短语-类名"的格式为关联命名, 其中的动词短语构成了可读的和有意义的顺序.
诸如"拥有"或"使用"这样简单关联名称通常是拙劣的, 因为这种名称不会增强我们对领域的理解.

通俗的说, 大部分属性类型应该是简单数据类型, 比如数字和布尔. 通常属性的类型不应该是复杂的领域概念.

应该通过关联而不是属性来表示概念类之间的关系.

顺序图
应该为每个用例的主成功场景, 以及频繁发生的或复杂的替代常见绘制顺序图.
在对软件应用将如何工作进行详细设计之前, 最好将其行为作为"黑盒"来调查和定义, 系统行为描述的是系统做什么, 而无需解释如何做.
系统时间应该在意图的抽象级别而非物理的输入输出设备级别来描述, 比如enterItem要优于scan, 因为前者即捕获了操作的意图, 又保留了抽象性, 而无需涉及到使用什么样的接口来捕获系统事件.系统事件的名称以动词开始, 这样可以提高清晰程度, 因为这样可以强调这些事件是命令或请求.

GRASP
RDD是思考OO软件设计的一般性隐喻. 把软件对象想象成具有某种职责的人, 他要与其他人协作以完成工作. RDD使我们把OO设计看作是有职责对象进行协作的共同体.

控制器
在正常情况, 控制器应该把需要完成的工作委派给其他的对象. 控制器只是协调或控制这些活动, 本身不完成大量工作.

高类聚
高类聚模式是对现实世界的类比, 显而易见, 如果一个人承担了过多不相关的工作, 特别是本应该委派给别人的工作, 那么此人一定没有很高的工作效率.

"不要和陌生人说话"
该约束限制了你应该在方法里给哪些对象发送消息, 它要求在方法里只应该给以下对象发送消息:
this对象
方法的参数
this的属性
作为this属性的集合中的元素
在方法中创建的对象
其意图是避免客户与间接对象和对象之间的对象连接产生耦合
直接对象是客户的熟人, 间接对象是陌生人, 客户应该和熟人讲话, 而避免和陌生人讲话.

架构分析
变化点和进化点
变化点:当前现有系统或需求中的变化之处
进化点:现有需求中不存在, 但可能在将来发生, 推测性的变化点.

决定在何处花费精力进行必要的设计, 预防将来可能的 变化, 这是架构设计师的艺术

架构分析关注的四个方面:
1)特别关注非惯性的需求, 包括对应用的业务或者市场环境的熟悉. 同时, 功能性需求也不能忽略; 它提供了处理这些架构因素的上下文, 更进一步, 识别功能性需求的可变性对架构分析也至关重要
2)涉及系统级别的, 大尺度的, 涉及面广的问题. 解决这些问题通常涉及到大尺度或者基础的设计决策.
3)对相互依赖的关联的权衡, 例如改善安全性可能会影响到实行效率和可用性, 这些决策大都会影响成本.
4)对可选方案的规划和评估.一个熟练的架构师既可以提供构建新系统的解决方案, 也可以对中备选方案进行评估.

架构分析指的是在功能需求的上下文中识别和解决非功能性需求.

异常
给一个异常命名, 这个名字要能够描述这个异常为什么被抛出, 而不是要描述抛出者. 这样做, 能够使程序员更容易理解问题, 并且突出了众多异常的相似之处的本质.



你可能感兴趣的:(设计模式,应用服务器,领域模型,读书,UML)