第60篇随笔:《道法自然》读书笔记

这是今年4月份读《道法自然》的时候记得读书笔记,以前记录到公司的论坛上了,今天整理了一下,放到这里,这本书是不错的书,刚刚接触面向对象开发的朋友可以看看,记得有意思的事情就是,我买了这本书回到公司发现同事Weny也买了一本,很巧,也说明书不错呀。

《道法自然》读书笔记

P1-1.1

关系到软件软件质量的问题已经严重制约了我们的发展,客户的投诉、合作伙伴的批评与日剧增。我得希望是通过这个新的

项目,尝试一些新的方法论、新工具和新方法,找到一些既能有效的提高开发效率,又能保证产品质量的解决方案。

P5-1.2

当项目组面临两难的选择是,首先要用鱼和熊掌来识别矛盾的两个对立面。项目组用“小鱼”来比喻那些开发和维护代价较

小、结构较简单但是缺乏某些灵活性的设计方案,用“熊掌”来比喻哪些灵活、易扩展,但结构复杂,开发和维护成本较高

的设计方案。在选择时:在满足需求的情况下尽量选择小鱼而舍弃熊掌;只有存在无可之一的理由时,才选择“熊掌”作为

设计方案。

P6-1.3

项目目标和项目范围

确定项目目标和范围是需求分析的第一个步骤,因为只有确定了项目的目标,开发人员才能够对整个项目的最终目的和前景

有更为深刻的认识;而只有确定了项目的范围,开发人员才能确定哪些需求是本项目组的需求。

P8-1.4.1

什么是需求?

软件需求是用户为了解决自己业务领域的问题,对软件产品明确的期望和要求。需求描述中不应包括设计细节、实现细节、

项目计划信息或测试信息等内容,因为需求本身与这些内容没有关系,需求关注的是我们究竟想开发什么和必须开发什么。

需求说明书也可以被看作是客户和项目组之间的一份和约,项目组只有完成了需求说明书的所有要求,软件产品才能交付给

用户使用。

P8-1.4.2

功能性需求和非功能性需求

功能性需求:一个系统、软件或者系统组件所必须完成的功能。功能性需求定义了系统的行为,也就是系统的软、硬件组件

在由输入到输出的过程中,对输入所作的基本的处理和转换。

非功能性需求:在软件工程领域,非功能性需求不是描述软件将做什么,而是描述软件如何完成这些功能。如,软件性能需

求、软件外部设备接口需求、软件设计约束、软件质量要求、可*性、响应时间、存储要求等。通常情况下,非功能性需求

很难测试,只能对他们进行主观评估。

在需求分析中非功能性需求很容易被程序员忽略。

P9-1.4.3

项目干系人

项目组成员的最终目标是通过技术手段设计和实现软件产品,项目干系人的关注点是正在开发的产品是否符合自己的利益需

求。

项目干系人包括:客户(Customer)、用户(User)、其它人(老板、领导等)

P10-1.4.4

需求分析

软件项目的需求分析经历下边一些步骤:

(1)确定项目的目标和范围;

(2)根据项目的目标和范围分析处所有的项目干系人;

(3)提取出所有的非功能性需求;

(4)分析出所有的功能性需求,现在一般采用用力分析的方法进行;

(5)编写《需求说明书》。

P13-1.5.1.3

只实现你真正需要的东西

只实现你真正需要的东西,不要去实现你认为需要的东西。

真正伟大的程序员是懒惰、缺乏耐心和傲慢十足的。

在需求分析的时候不要想太多离谱的东西。

均衡三角形:资源、进度、特性

P16-1.5.2.2

挖掘需求

在用户面前,项目组成员应当承担起解释和建议的职责,但有关需求的最终决定必须由用户做出。

在具体软件的原型面前,用户当然可以根据自己的想法,提出建议。

P20-1.5.2.3

编写需求说明书

一般而言,描述需求的文句应尽量简单,采用清晰、明白的“主谓宾”句式。

包括内容:项目的目标、范围、用户、非功能性需求和功能性需求。可以附加:系统局限性、读者对象、参考文档、术语、

缩写、产品介绍、产品面向用户群体、产品应遵循的标准、规范、市场上同类产品等内容。

P22-1.6.1

需求变更的原因和对策

(1)开发中碰到的突发问题。

(2)开发人员与用户沟通造成的问题。

(3)项目组成员的失误。

我们所处的环境就是一个变化的环境,所有的开发人员都应该勇敢的面对显示,面对变化并拥抱变化。当然,拥抱变化也不

是就要放任变化,我们必须将变化进行有效的管理和控制,把变化限制在合理的范围内。一般来说,通过迭代开发的方式,

在开发过程中增加反馈环节,可以将需求变化控制在最小的范围内。

P30-2.4

用例建模

用例建模就是通过分析用户的功能性需求,得到用例模型的工作过程,为了使用例的三要素都在用例模型中得到体现,用例

建模一般包括一下几个步骤:

(1)确定系统边界。

(2)确定参与者。

(3)找出所有的用例。

(4)确定每个用例的级别。

(5)编写用例的文字描述。

(6)画出整个系统为对象的顺序图。

P31-2.4.1

确定系统边界和参与者

系统的便捷就是将系统的功能特性与系统的外部环境分离开来的逻辑分界线,一个完整的软件系统通常包含复杂的内部结构

,可以有外向内细分为若干个层,当我们考察系统的用例模型的时候,一般要实现明确我们考察的是系统的哪一个层次。

P33-2.4.2

确定用例级别

用例界别只得是我们对用例模型的抽象和细化程度。如果从不同的高度或不同的层次看待同一个问题,我们就可以根据需要

将用例模型细化到某个合适的程度。常用的用例级别包括:高层用例、用户目标级用例和子功能用例。

高层用例:高屋建瓴的考察全局问题,了解系统需要为用户提供几大类功能。

用户目标级用例:它的作用是从用户的观点来关系软件系统,了解用户究竟需要哪些功能特性,这个级别评比了很多低级别

的信息。

子功能用例:被高层用例和用户级用例屏蔽的低级别信息反映在子功能用例中。

《编写有效用例》中报从高到底的不同用例级别形象的比喻为云朵、海平面、海平面一下的余下等自然界事务。我们既可以

在云中漫步,也可以来一个海底总动员。

用户级用例的描述信息:用例名称、系统范围、用户目标、前置条件、执行过程、扩展、后置条件

高层用例描述信息:用例名称、系统范围、描述

P36-2.4.2.3

子功能级用例和用户目标级用例之间存在包含(Include)和扩展(Extend)两种关系。

包含关系:用户目标级用例的某一个步骤会调用那个该子功能级别的用例,这一贯关系类似于函数的调用关系,被包含的用

例一定会被执行,在用例图中表现为从包含用例指向被包含的用例的箭头。

扩展关系:在某种条件满足的条件下,系统会从用户目标级用例转而执行该子功能级用例,执行时需要满足的条件为扩展点

,在用例图上表现为从扩展用例指向被扩展用例的箭头。

P47-3.2

面向过程的设计方法时对现时世界的简单抽象,它通常只能按照软件的功能特性,易函数为单位对系统进行分解,这种分解

没有考虑到,显示世界中的物体往往通常都是属性和行为的复合体。因此,面向过程的设计方法更适合于哪些易功能操作为

主,对复用性和扩展性要求不高的软件系统。

传统的面向过程设计方法就是对功能分解与逐层迭代思想的体现。这种方法要求我们按软件的功能特性,在不同级别上,把

系统划分为多个功能模块,并保证模块间的耦合度最小。

P51-3.4.2

面向对象的基本概念

封装:通过封装,我们可以把类(Class)作为软件中的基本复用单元,提高其内聚度、降低其耦合度。

继承(Inherit)的缺陷:

(1)过大的继承树会严重降低软件的可读性。

(2) 继承是在编译期间通过静态绑定实现的,仅通过继承机制,我们没有办法在程序运行期间动态改变属性或方法的绑定

关系。

除了继承以外我们可以使用聚合、委托、组合等关系来实现类与类之间的相关性。

补充:

聚合意味着一个对象拥有另一个对象或对另一个对象负责,一般我们称一个对 象包含另一个对象或者是另一个对象的一部

分。聚合意味着聚合对象和其所有者具有相同的生命周期。
相识意味着一个对象仅仅知道另一个对象。有时相识也被称作“关联”或“引用”关系。相识的对象可能请求彼此的操作,

但它们不为对方负责。相识是一种比聚合要弱的关系。它只标识了对象间较松散的耦合关系。

P55-3.4.3

面向对象的基本原则

开闭原则:一个没扩对扩展应是开发的,对修改是关闭的。

这里所说的模块包括类和函数。简单的说,该原则要求我们的代码模块应能很容易的扩展,大师在扩展的过程中,无须改动

已有的代码。

完全替换原则:派生类应该能完全替换掉基类。

完全替换指的是在需要一个基类指针或积累引用的地方,传递一个派生类的指针或引用,代码也能正常工作。要想使派生类

完全替换基类,派生类与基类必须拥有相同的接口定义。此外,对接口中的每一个方法,派生类和基类还必须拥有相同的前

置条件和之后条件。

依赖倒置原则:依赖于抽象,而不要依赖于具体的对象。

简单的说就是对接口编程,而不要对具体的对象编程。

非循环依赖原则:包和包之间不能有循环依赖的关系。

只实现你真正需要的东西,不要去实现你认为需要的东西。

不要重复自己:任何代码只出现一次。

保持简化的设计。

为人写代码,而不是为机器编写代码。
 
P58-3.4.4

面向对象的开发过程

(1)面向对象分析:根据用户的需求,建立一个准确、

完整、一致的系统模型。这个系统模型更多的侧重于描述

软件需要解决的问题是什么样。

(2)架构分析:主要从宏观上考虑一个软件系统该如何

组织,以及该软件系统需要满足的设计约定、规则和模式

等。这些设计策略决定了软件系统由哪些结构性的组件组

成,规定了这些组件之间结构及他们协作的方式。

(3)面向对象设计:以此前得到的分析模型作为输入,

把分析模型转化成描述如何解决问题的系统模型,得出完

整的设计方案。

(4)编码。

(5)测试。


模式的分类

架构模式:描述了软件系统的基本机构组织策略。

设计模式:描述了在软件系统的某一局部不断重现的核心解决方案,这种解决方案一完善的设计结构出现,可以被应用到以

后出现的类似语境中。

通用这则分配软件模式(GRASP模式):描述了在面向对象设计过程中把职责分配给系统中不同对象的有效经验和基本原则

P69-4.3.2

蕴涵在设计模式中的设计原则和理念

(1)设计模式最根本的意图是适应需求变化,对于不变的部分滥用设计模式就会造成“过度设计”。

(2)针对接口编程,而不要针对实现编程,针对接口编程的组件不需要知道对象的具体类型和实现,只需要知道抽象类定

义了哪些接口,这减少了实现上的依赖关系。

(3)优先使用聚合,而不是继承。

P87-5.3.1

面向对象分析于面向对象设计的区别

在侧重点上,面向对象分析侧重于理解问题,描述软件要做什么,而面向对象设计侧重于理解解决方案,描述软件要如何做

面向对象分析一般只考虑理想的设计,不关心技术和实现层面的细节,而面向对象设计需要得到具体、更详尽,更接近真是

代码的设计方案。

在设计结果的描述方式上,面向对象分析阶段侧重于描述对象的行为,而面向对象设计阶段侧重于描述对象的属性和方法。

面向对象分析只关注功能性需求,而面向对象设计即关注功能性需求,也关注非功能性需求。

面向对象分析产生的系统模型规模通常较小,而面向对象设计产生的系统模型规模较大,内容也比较完整、详尽。

P89-5.3.2

实体类和软件类

实体类(Entity Class):是应用领域中的核心类,一般是从显示世界中的试题对象归纳和抽象出来的,用于长期保存系统

中的信息,以及提供针对这些信息的相关处理行为。一般情况下,实体类的对象实力和应用系统本身有着相同的生命周期。

边界类(Boundary Class)侍从哪些系统和外界进行交互的对象中归纳和抽象出来的,也就是说,边界类是系统内的对象和

系统外的参与者的联系媒介,外界的消息只有通过边界类的对象实例才能发送给系统。

控制类(Control Class)是实体类和边界类之间的润滑剂,是从控制对象中归纳和抽象出来的,用于协调系统内便捷类和

实体类之间的交互。

P92-5.3.3

用例驱动的面向对象分析工作

一个完整的面向对象分析过程包括从用例中提取实体对象和实体类、添加边界类、添加控制类、提取属性、提取分析类间关

系、绘制类图和顺序图、编者术语表等几个步骤。

P111-6.3.3.1

在进行系统分层时,要注意以下几点:

1:层与层之间的耦合应该尽可能的松散,这样,只要保证接口的一致,某一层的具体实现旧很容易被扩展和替换。

2:级别相同、职责类似的元素应该被组织到同一层中。

3:复杂的模块应该被继续分解为粒度更习的层或子系统。

4:应尽量将可能发生变化的元素封装到一个层中,这样,变化发生时我们只要改变受影响的层就可以了。

5:每一层应当只调用下一层提供的功能服务,而不能跨层调用。

6:每一层绝不能使用上一层提供的功能服务,也就是说,决不能在层与层之间造成双向依赖或循环引用。
 
P116-6.3.3

使用MVC模式时,一般要满足一下几项基本要求:

1:同一信息可以在不同的窗口中显示。

2:数据的变化及时在显示窗口中反映出来。

3:用户接口要很容易改变,甚至可以在运行时改变。

4:不同的用户接口风格不会影响应用程序的核心逻辑。


面向对象设计工作包括以下几个步骤:

1:细化和重组类。

2:细化和实现类间关系,明确其可见性。

3:增加遗漏的属性,指定属性的类型和可见性。

4:分配职责,定义执行每个职责的方法。

5:对消息驱动的系统,明确消息传递方式。

6:利用设计模式进行局部设计。

7:画出详细的顺序图和协作图。

P144-7.3.4

增加遗漏的属性,指定属性类型和可见性


按照面向对象强调数据封装的思路,类内部封装的数据不应该暴露给客户程序。更好的做法时把属性的可见性设置成私有或

保护的,然后添加getXXX()和setXXX()等共有的访问方法,以支持客户程序对属性的间接访问。虽然这种方法比较麻烦,但

它即能为属性添加存取时的控制和校验代码,又能屏蔽属性的实现细节,减少服务器代码的改变对客户程序的影响。因此,

在时间开发过程里,除了那些比较简单且不常发生变化的属性可以直接暴露给客户以外,其它属性最好公共setXXX()和

getXXX()等方法进行封装。

P146-7.3.5.1

什么是职责

面向对象系统中的类所承担的职责可以分为两个大类:

(1)“做”型职责:自己要做的事;自己要为其它对象提供某总服务;发送消息给其它对象以要求提供某种服务;控制和

协调其它对象的活动。

(2)“知道”型职责:知道自己封装了哪些数据;知道哪些对象和自己发生了关系。

posted on 2005-10-25 19:44  Duiker  阅读(2540)  评论(3编辑  收藏  举报

导航