软件研发基本设计规范

  • 格式:docx
  • 大小:28.20 KB
  • 文档页数:4

下载文档原格式

  / 6
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1 设计规范

这里主要摘取了OO设计原则的其中几条,其中开闭原则、里氏替换原则必须遵守,单一职责原则尽量要求遵守,接口分离、合成聚合、依赖倒置原则强烈推荐遵守,另外补充了一些其他规范。

1.1开闭原则(Open-Closed Principle, OCP)

这是最基本的原则,一个模块应当对扩展开放,对修改关闭。确切地说,模块的对外接口不能被修改,而只能被扩展,当某个开发者使用了你的接口,而却被你后期修改了这个接口,那对程序是一个灾难。

因此在进行设计时要尽量考虑接口封装机制、抽象机制和多态技术。

1.2单一职责原则SRP (Simple responsibility pinciple)

不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

很多人可能觉得它很简单,但在实际中,我们多有不遵守这条原则。即便是经验丰富的程序员写出的程序,也会有违背这一原则的代码存在。为什么会出现这种现象呢?因为有职责扩散。所谓职责扩散,就是因为某种原因,职责P被分化为粒度更细的职责P1和P2。

比如:类T只负责一个职责P,这样设计是符合单一职责原则的。后来由于某种原因,也许是需求变更,也许是程序的设计者境界提高,需要将职责P细分为粒度更细的职责P1,P2,这时如果要使程序遵循单一职责原则,需要将类T也分解为两个类T1和T2,分别负责P1、P2两个职责。但是在程序已经写好的情况下,这样做简直太费时间了。所以,简单的修改类T,用它来负责两个职责是一个比较不错的选择,虽然这样做有悖于单一职责原则。(这样做的风险在于职责扩散的不确定性,因为我们不会想到这个职责P,在未来可能会扩散为P1,P2,P3,P4……Pn。所以记住,在职责扩散到我们无法控制的程度之前,立刻对代码进行重构。)

遵循单一职责的优点有:

•可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;

•提高类的可读性,提高系统的可维护性;

•变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。

1.3接口分离原则(the Interface Segregation Principle ISP)

一个类对另外一个类的依赖是建立在最小的接口上。使用多个专门的接口比使用单一的总接口要好。如果说某个模块能提供接口能同时支持放大、缩小、平移操作,建议提供成三个接口,因为存在人们只需要某一个,或者某两个接口的情况,另外当其中某个操作出错时,也不会影响到调用另两个接口的人。

1.4合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)

在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分,新的对象通过这些向对象的委派达到复用已有功能的目的。这句话怎么可以理解为:要尽量使用合成/聚合,尽量不要使用继承。

举个例子,有一个对象壶,另一个对象浇水壶,也需要用到壶的内容,但是它额外有浇水的功能,使用壶和一个浇水的接口的组合来定义浇水壶更好于直接继承壶,因为水管也有浇水的功能。

1.5里氏代换原则LSP(Liskov Substitution Principle)

如果每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P 在所有的对象o1都代换称o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。换言之,一个软件实体如果使用的是一个基类的话,那么一定适用于其子类,而且它根本不能察觉出基类对象和子类对象的区别。只有衍生类可以替换基类,软件单位的功能才能不受影响,基类才能真正被复用,而衍生类也能够在基类的基础上增加新功能。反过来的代换则不成立。

最著名的例程为:正方形是否是长方形的子类(答案是"否")。类似的还有椭圆和圆的关系。

应当尽量从抽象类继承,而不从具体类继承,一般而言,如果有两个具体类A,B有继承关系,那么一个最简单的修改方案是建立一个抽象类C,然后让类A和B成为抽象类C的子类.即如果有一个由继承关系形成的登记结构的话,那么在等级结构的树形图上面所有的树叶节点都应当是具体类;而所有的树枝节点都应当是抽象类或者接口。

1.6依赖倒置原则(Dependence Inversion Principle)

高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应当依赖于细节,细节应当依赖于抽象。

问题描述:类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑;类B和类C是低层

模块,负责基本的原子操作;假如修改类A,会给程序带来不必要的风险。

解决方案:将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接

与类B或者类C发生联系,则会大大降低修改类A的几率。

依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。

依赖倒置原则的核心是接口编程。在实际编程中,我们一般需要做到如下3点:

1)低层模块尽量都要有抽象类或接口,或者两者都有。

2)变量的声明类型尽量是抽象类或接口。

3)使用继承时遵循里氏替换原则。

1.7共同封闭原则Common Closure Principle(CCP)

一个包中所有的类应该对同一种类型的变化关闭。一个变化影响一个包,便影响了包中所有的类。一个更简短的说法是:一起修改的类,应该组合在一起(同一个包里)。如果必须修改应用程序里的代码,我们希望所有的修改都发生在一个包里(修改关闭),而不是遍布在很多包里。CCP原则就是把因为某个同样的原因而需要修改的所有类组合进一个包里。如果2个类从物理上或者从概念上联系得非常紧密,它们通常一起发生改变,那么它们应该属于同一个包。

CCP延伸了开闭原则(OCP)的“关闭”概念,当因为某个原因需要修改时,把需要修改的范围限制在一个最小范围内的包里。