软件设计
设计就是把需求分析和编码调试连在一起的活动。
设计不是在谁的头脑中直接跳出来了,他是不断的设计评估,非正式讨论,写实验代码以及修改实验代码中演化和完善。
作为软件开发人员,我们不应该试着在同一时间把整个程序都塞进自己的大脑,而应该试着以某种方式去组织,以便能够在一个时刻可以专注一个特定的部分。这么做的目的是尽量在任意一时间减少要考虑的程序量。
在软甲架构的层次上,可以通过把真个系统分解成多个子系统,来降低问题的复杂度。人类更容易理解和接受多项简单的信息,而不是一项复杂的信息。所有软件设计技术目标都是把,复杂问题分解成多个简单的问题,减少子系统直接的项目依赖,增加子系统内部的聚合。
保持子程序的短小精悍也能帮助你减少思考负担,从问题领域入手,而不是从底层实现细节入手去编程程序,在最抽象的层次上工作,也能减少人的脑力负担。
编写代码一个评估质量的标准,就是要写出既让自己容易理解,也能让别人看懂,而且很少有错误的程序代码。
如何管理复杂度:
①把任何人在同一时间需要处理的本质复杂度减少到最低。
②不要让偶然性的复杂度无谓的快速增长。
下面列出一些设计范畴内的特征:
①最小复杂度,避免做出聪明的设计,因为聪明的设计常常难以理解。
②易于维护,设计时候为做维护的程序员着想,设计能自明的系统。
③松散耦合,老生常谈的特征,实现方法接口隔离,依赖倒置等等
④可拓展性,明确系统中那些需求是容易发生变化,例如改变一种表现方式,增加一种新的事物等等,在增强系统功能时候,减少或者不影响已有的功能,是最佳的拓展性的表现。
⑤可重用性, do not repeated your self。
⑥高扇入,就是说让大量的类使用某个特定的类。 这说明设计系统很好的利用在较低层次上的工具类 unit.cs
⑦低扇出,就是说让一个类,少量或者适用使用其他类。这样可以降低类与类之间的复杂程序,例如使用中介者模式,使用父类对象,能够很好的处理这类问题。
⑧可移植性
⑨精简性,系统没有多余的部分。要问这个关键的问题:这个虽然简单,但是把它加入之后会损害什么呢?
⑩层次性,尽量保证各个系统各个分解的层次性,能够是你的程序能在任意层面上观察,并得到某种一致的看法。设计出来的系统应该能在任意层次上观察而不需要进入其他层次。
11.标准技术,一个系统所依赖的外来的,越古怪的越多,别人在第一次想要了解它的时候就越头疼。尽量使用标准化,常用的方法,让整个系统给人一种熟悉的感觉。
设计层析
第一层,软件系统
第二层,分解为子系统或者包
为了让子系统的链接简单易于维护,就要尽量简化系统之间的交互关系。最简单的交互关系是让一个子系统去调用另一个子系统中的子程序。稍微复杂一点的交互关系,是在一个子系统中包含另外一个子系统中的类,而最复杂的交互关系是让一个子系统中的类去继承另外一个子系统中的类。但是要注意,系统层次设计图应该是无环图。
第三层,分解为类
把子系统进行适当的分解,并确保分解出的细节恰到好处,能够用单个的类实现。
第四层,分解成子程序
第五层,子程序内部的设计
面向对象设计方法,设计步骤
辨识对象及其属性(方法和数据)
确定可以对各个对象进行的操作
确定各个对象对其他对象的操作方法
确定对象哪些部分对其他对象是可见的,那些是不可见的。
定义每个对象的公开接口
形成一致的抽象
抽象是一种能让你在关注某一概念的同时可以放心的忽略其中一些细节的能力。
基类也是一种抽象,它使你能集中注意力去关注某一组派生类所具有的的共同特性,并在基类的层次上忽略各个具体派生类的细节。一个好的接口也是一种抽象,它能够让你关注接口本省,而不是类的内部工作方式。
封装实现细节
封装是填补类抽象留下的空白,抽象是说:可以让你从高层次的细节来看待一个对象。 而封装则说:除此之外,你不能看到对象的任何其他细节层次。
你能看到的就是你能全部得到的。好的类接口就像冰山的尖一样,让类的大部分内容都不会暴露出来。
循环依赖,一种更隐晦的信息隐藏障碍则是循环依赖,比如A类中子程序调用B类中的子程序,然后B类中的子程序有调用A类中的子程序。要避免形成这种循环依赖,它会让系统难于测试,因为你无法单独测试A类或者B类,
耦合种类:
简单参数耦合,当两个模块之间的通过参数来传递,并且所有的 数据都是简单的数据类型(Primitive data type)的时候,这两个模块之间的耦合关系就是简单参数耦合,这种耦合关系是正常的。
简单对象耦合,如果把模块实例化一个对象,那么他们之间的耦合关系就是简单对象耦合,这种耦合关系也不错。
对象参数耦合,模块1要求模块2传给obj3.那么这两个模块就是对参数对象的耦合,这种耦合关系更为紧密,他要求模块2了解obj3.
语义上的耦合,最糟糕的耦合关系。语义上的耦合是非常危险的,因为更改被调用模块中的代码,可能会破坏调用他的模块,破坏方式是编译器完全无法检查的。
松耦合的关键之处在于,一个有效的模块提供出一层附加抽象,一旦已写好,你就可以当然的去调用它,这样就降低了整体系统的复杂度,是的你可以在同一时间只用关注一件事。如果对一个模块的调用要求你同时关注好几件事,其内部工作细节,对全局数据修改,不确定的功能等,那么就失去了抽象的能力,模块所具有管理复杂度的能力也会虚弱或者完全丧失。
类和子程序是用于降低复杂度的首选和最重要的智力工具,如果他们乜有帮助你简化工作,那么他们就是失职。
设计模式通过把设计对话提升一个更高的曾是上来简化交流,处理在管理复杂度方面的益处之外,设计模式还能够让设计者在更高一层的粒度上进行思考与讨论,从而加速设计交流的过程。
模块化这一概念和信息隐藏,封装以及其他的设计启发密切相关。
关于设计启发的总结:
寻找现实世界的对象,形成一致的抽象,封装实现细节,在可能的情况下继承,信息隐藏,找出容易改变的区域,保持松耦合,探寻通用的设计模式,
下列启发方法有时也很有用:
高内聚,构造分层结构,严格描述契约,分配职责,为测试而设计,避免失误,有意识的选择绑定时间,创建中央控制点,考虑使用蛮力,画一个图,保持设计模块化,