UML面向对象设计基础(异步图书)_note2_第一部分完
原文名称fundamentals of object-oriented design in uml
可以结合英文原版进行阅读
第二章 面向对象简史:
-
面向对象的起源
-
Larry Constantine: 提出软件在进行编程之间需要进行设计. 提出了耦合, 内聚的观点
-
J.Dahl 和 K.Nygaard: 引入了类的概念, 并令该概念出现在
Simula
语言中 -
Alan Kay, Adele Goldberg, etc: 提出了
Smalltalk
语言, 这一语言包含了许多现在面向对象的概念如消息和继承 -
Edsger Dijkstra: 提出
软件正确性的理念 (conscience of software correctness)
, 并提出了使用抽象层构造软件
的观点, 在两个相继的层之间使用严格的语义区分, 是一种封装方式 (看不懂) -
Barbara Liskov: 推动了抽象数据类型(ADT)的发展, 为面向对象奠定了基础, 成果为
CLU
语言, 支持隐藏内部数据的表示法 -
David Parnas: 提出了模块软件构造原则. 其中一些信息隐藏的基本思想可以应用到面向对象的系统中
-
Jean Ichbiah etc: 开发了
Green
语言, 是被美国国防部采用的Ada
语言(现称Ada-83
), 创建了一般性和包的概念 -
Bjarne Stroustrup: 创建了C++语言.(一句话顶千句话)
-
Bertrand Meyer: 创建了
Eiffel
语言.(我觉得作者开始推销自己的爱好了) -
Grady Booch, Ivar Jacobson, Jim Runbaugh: 创建
UML
统一建模语言(来了来了)
-
-
面向对象的成熟期
-
本章节主要介绍工业界如何促进面向对象时代的到来
-
面向对象软件工程的历史重演了传统软件工程的历史
-
软件设计是在编写代码之前对代码的相关部分进行规划. 这种行为可以为人们解决潜在的维护问题
-
再加上许多软件虽然设计严谨,可维护性高,但是不能满足用户的需求. 为了满足用户的需求, 更多有规律的以及严格的分析方式应运而生
-
目前已经有
计算机辅助软件工程(CASE)
. 目前这些软件已经在联邦保护软件中获得了声誉Federal Protection Program
. 这些建模工具帮助我们进行需求的分析, 软件的设计, 软件构造, 使得软件开发和维护更加容易被管理 -
面向对象的软件设计不是万能的, 如果不按照本书后面的内容进行精心设计, 那么面向对象也不能提供可重用的以及可靠的软件. 发生这种情况主要的原因是项目管理者对面向对象缺乏真正的认识
-
面向对象编程的概念大约在1980年代开始流行, 在1990开始出现面向对象的数据库管理系统和面向对象的建模工具
-
作者认为下一场与面向对象同等水平的计算机技术革命是
分布式组件软件
, 这部分内容会在第15章进行一定的讨论
-
-
类似工程学的面向对象
-
软件工程可以根据以下分类: 类; 技术; 系统. 类是可以组合的基本构造单元, 通过适当的技术而产生系统
-
选择有用的电路封装在芯片中有赖于工程师对于电路的正确标识.人们会去购买芯片用于操作放大器,计时器,驱动器等, 但是没有人愿意去购买晶体管,电感器,以及电阻的大规模集成芯片然后从头做起
-
在软件中我们必须确保开发的类有效, 健壮, 易于抽象
-
-
如果IC不能被组合则几乎是无用的, 而电子工程师们为了将IC组合在一起印刷出了电路板
-
在开发面向对象的软件时,必须进行Macro层的设计(我理解是要进行最上层的宏观设计), 在这一层次上处理类以及对象之间的联系. 显然类的内部设计与更高层次的类间设计有着紧密的关系. 和电子工程类似: PCB的布局依赖于继承于其上的IC的设计程度. (这翻译真难受)
-
在类的内部层次和类间层次上都存在着对象设计的优劣. 因此好的面向对象系统的设计不仅取决于高质量的抽象还取决于建立这些抽象的上层技术
-
这里的翻译真的是不行… 把原文贴上来也好啊… 这里是我的个人理解:
对于软件系统的层次,作者分成了三层, 由底层到高层分别为:
1. 类层 -- 实现软件的各个类
2. 技术层 -- 实现类之间的互联互通, 相互耦合的方式
3. 系统层 -- 作者没有太讲清楚这一层是做什么, 但是我觉得应该是指由技术层构建的模块在此拼装为系统
在开发面向对象软件的时候, 我们首先进行系统层的设计, 再进行技术层的设计, 再进行类层的设计
但是由于底层的设计也会影响上层的设计. 对于类的实现的设计也会影响到类间关系的设计.
-
-
-
面向对象的益处 (这个标题翻译的有点问题)
-
-
面向对象对于企业的六个主要的软件活动的影响:
-
对于用户需求分析的影响:
-
已存在的问题:
-
对于用户需求的结构化分析的主要难点是确定过程分析和数据分析之间的边界
-
由过程分析获得的数据流图和通过数据分析得到的实体关系图容易出现矛盾,难以共存
-
这些过程和数据的矛盾在一些实时系统中非常常见, 例如过程与数据模型的对应关系并不清晰
-
-
面向对象对这一问题的解决:
-
在软件开发的生命周期的早期就开始将过程和数据研究融合在一起
-
在面向对象设计中
动态与静态分析
(另一种方式的过程和数据分析
)可以将过程和数据很好的结合起来 -
有人形容面向对象的
动态与静态分析
描述为爱因斯坦相对论将空间与时间进行的融合
-
-
-
对于软件设计的影响:
-
面向对象的优势: 能够使设计者将软件中的棘手问题使用封装特性封装起来
-
一些常见的棘手问题如:
-
复杂数据结构
-
复杂组合逻辑
-
详细的过程
-
数据间的关系
-
高深的算法
-
复杂设备驱动程序
-
后续的阅读笔记不再基于异步图书的翻译, 而是基于英文原版
-
面向对象的缺点: 应用封装和继承特性使得结构本身变得复杂.
In object orientation it is all too easy to create a Gordian hammock of inextricable interconnections (这里的意思是会形成像吊床绳一样难解的复杂互联关系) that either is unbuildable or will result in a system that runs about as fast as a horse in a sack race.
-
为了解决这一问题, 作者在第二部分介绍UML的一些重要功能. 在第三部分作者会提供一些设计原则和标准帮助我们对于设计进行评价.
-
通过这些UML工具和评价标准达成的目标是: 使得建立的模型在构成一个系统的时候可以相互合作, 但是将其分开的情况之下又是
maintainable
的 -
虽然在软件设计方面OOP可能需要一些额外的工作, 但是在完成整个软件的设计以及开发之后会提供
温顺但复杂的对象集合
— 帮助后续的维护与开发
-
-
对于软件构建的影响:
-
主要的优势点:
-
reusability
-
对于代码的重用水平是在
class level
而不是在子程序水平 -
通过维护你自己的类库, 你实际上是在开发一个专属于你自己的高级编程语言
-
对于面向对象而言, 其有足够的能力在你公司的项目之间到处迁移, 以一种自洽的软件模块的形式
-
至少对于携带了辅助类的类而言, 其完全可以作为一个自洽的独立模块存在
-
-
reliability
关于可靠性是老生常谈的话题, 只有当你能够以某种方式验证自己代码的正确性时, 你才能认为你的代码具有了可靠性
OOP中通过一种被称作
class invariants
的断言形式进行代码的正确性的判断这种
class invariants
是通过提供一些所有满足设计的对象都要满足的条件达成的. 例如对于类Person
而言,Person.birthdy <= todayDate
是永远成立的通过在代码中加上这样的判断断言, 可以非常彻底的审核代码的正确性. 在进行一次代码审核的时候可以核查代码的中间状态是否符合设计
但是面向对象并不能保证代码完全正确. 面向对象的设计思路只是帮助你能够更加便捷的确定你写的代码和你脑海中的运行流程是一致的
-
rebustness
-
鲁棒性的定义 : 当出现错误的时候能够从错误中恢复. 一般出现的错误有以下这几种:
-
断言不符合
-
内存冲突
-
外部设备出错
-
计算overflow
-
-
应用从这些问题中恢复的方法是: 捕获这些异常情况, 然后开始运行一个子程序, 用于从错误中恢复
-
在一些OOP环境中, 你可以监控每一个
class invariants
以及其他的断言判断. 如果发生错误就进行应用恢复 -
当然一个可以选择的方式是没有错误处理, 也就是如果出现错误就让应用崩溃掉. 当然这样的设计不是具有鲁棒性的设计
-
-
extensibility
-
一个易于拓展的应用程序需要在设计领域和实现领域的同型性
简单来说就是令你的解决方案和问题符合. 为了达成这一目的, 你需要保证一个用户的小小改动不会成为系统的噩梦 -
在面向对象的设计中, 相较于其他设计方法, 你会更少的创建一些晦涩难懂的构件. 因为OOP在进行构件的构建时站在一个较高的层次, 同时可以引用很多真实生活中的抽象概念. 所以OOP更加接近于
同型性
的目标 -
另外可拓展性和可继承性是息息相关的. 人们试图拓展一个系统的时候总是试图在一些已经写好的模块上增加一些功能. 例如: 我们不能简单的使用客户的概念, 我们要使用国内客户和国外客户. 对这种情况, 只需要对于父类进行继承即可
-
-
distributability (这里不是可分布性, 更多的是指泛用性)
-
在一个叫做
CORBA
的项目中, 程序员通过OOP将不同硬件平台的接口进行了整合, 使得上层的应用开发人员只需要编写简单的单线程应用, 由CORBA
处理复杂的底层细节
-
-
storability
-
可存储性, 这里主要的案例是OOP数据库.
ODBMS
可以存储任何类. 通过提供面向对象的封装,继承,多态的特性. 目前已经存在OQL
用于在数据库中代替SQL
-
-
-
-
对于软件维护的影响
-
重用性, 可靠性, 鲁棒性, 可拓展性是软件维护的四大支柱
-
OOP以以下的方式减少维护成本;
-
可重用性减少了需要维护的代码量
-
可靠性减少用户的抱怨和难以忍受的修正问题
-
鲁棒性保证了应用在实际生产环境中不会完全崩溃
-
可拓展性保证了当用户要求更多功能或者进行改进的时候不会代价过高
-
-
-
对于软件使用的影响 — OOP是GUI软件编写的一个重要工具
-
概念上的: OOP和GUI界面在属性上具有共通性 – 因为GUI设计中的按键以及选项是离散的, 每个控件都有其特定的信息接口.
-
例如: 对于不同列表的设置可以通过继承进行实现,
-
对于一个选项表加上一个Start按钮的情况, Start按钮的实际运行内容需要依赖选项表中被选中的选项. 这里就是使用多态的好地方
-
-
实践上的: 许多进行GUI编程的商业库是通过OOP进行的, 因为GUI程序本身就有OOP的属性
-
-
软件项目管理:
-
OOP的一些技术属性对于项目管理也有价值
-
减少维护消耗以更好的处理软件的积压需求
-
公司组织架构上的改变
-
OOP由于通过代码重用创建了很多的库, 也就意味着需要要库管理员
-
编程人员会被分为两个部分, 一个思考如何创建新的类, 一个思考如何使用现有的类实现应用需求
-
通过增加重用性减少了对于实际码代码的重视程度,而增加了对于需求的分析能力
-
UML等工具的广泛应用使得在需求分析领域和软件设计领域的符号系统有了一致性
-
-
但是由于需要组织架构上的改变, 员工也需要适应自己的角色, 例如要学会如何设计类使得其更能被重用
-
-
OOP在项目管理上的高效性需要项目管理人员将其当作实现项目管理的手段, 而不是实现项目管理的目的
-
在项目管理中使用OOP首先要知道你最关心的什么性能指标, 然后通过OOP工具进行达成
-
如果在使用OOP的时候不明确自己的目标, 那么由面向过程过度到面向对象的代价就似乎毫无意义了
-
只有你同时知道你在做什么以及为什么这么做, 理财能通过耐心达成设计中的目标
-
-
-
-
本章小结
-
OOP是软件发展的一个正常步骤, 不能将其神化也不能忽视其意义
-
OOP解决了以下两个问题
-
解决了数据和过程之间的分裂, 在软件设计和需求分析中使用不同符号的问题
-
解决了信息与实时系统开发方法的分离问题.
-
-
通过
class invariance
达成可靠程序 -
通过重用减小维护成本
-
通过和GUI配合, 支持GUI程序的开发
-
只有通过良好的管理架构,才能充分发挥OOP的效果
-
-
习题
-
IC之间的连接是匿名的. 但是对象之间的连接时具名的
-