软件架构(软件体系结构)-设计原则篇(七大设计原则)

软件架构(软件体系结构)-设计原则篇(七大设计原则)

1、软件架构设计原则概述

1.1、软件的可维护性

1、软件的维护

一个好的软件设计可维护性较好的系统,必须能够允许新的设计要求很容易地加入到已有的系统中。

2、具有可维护性的设计目标

一个好的系统设计应该有如下所示的性质:

  • 可扩展性:新的性能可以很容易的加入系统中。
  • 灵活性:代码修改不会波及很多其他的模块。
  • 可插入性:可以很容易地将一个类用另一个有同样接口的类代替。

1.2、系统的可复用性

1、传统的复用:

  • 代码的剪贴复用:容易产生错误
  • 算法的复用:将已经得到很好的研究的算法拿来复用
  • 数据结构的复用:将研究透的数据结构拿来复用。

2、面向对象向设计的复用

面向对象的语言中(Java),数据的抽象化、继承、封装和多态性等语言特性使得一个系统可在更高层次上提供可复用性。

1.3、可维护性复用、设计原则和设计模式

在面向对象的设计中,可维护性复用是以设计原则和设计模式为基础的。

设计原则是在提高一个系统可维护性的同时,提高这个系统的可复用性的指导原则,依照这些设计原则进行系统设计,可以实现可维护性复用。

设计原则包含以下七种:

  • 开-闭原则
  • 里氏代换原则
  • 依赖倒转原则
  • 接口隔离原则
  • 组合聚合复用原则
  • 迪米特法则
  • 接口隔离原则
  • 单一职责原则

设计模式又分为以三大类别:

  • 创建模式
  • 结构模式
  • 行为模式

考虑篇幅问题,本篇终点讲解设计原则,三大类别设计模式另外写博客进行讲解。

下面开始七大设计原则的讲解。

2、开- 闭原则

概念:对扩展开放,对修改关闭(精髓)。

在设计一个模块中,应当使这个模块在不被修改源代码的前提下被扩展——改变这个模块的行为。

所谓的开始,是用抽象构建框架,用实现扩展细节。可以提高软件系统的可维护性和可复用性。开闭原则是面向对象中最基础的原则,实现开闭原则的基本思想就是面向抽象编程。

与其它原则之间的关系

(不了解其它原则也别急,继续往下看,看完后再回过来看关系,说不定另有收获!)

  1. 里氏代换原则:任何父类可以出现的地方,子类一定可以出现。是对开-闭原则的补充,是实现抽象化的具体步骤的规范。
  2. 依赖倒转原则:要依赖于抽象,不要依赖于实现。依赖倒转原则与开-闭原则之间是目标和手段之间的关系:要想实现“开-闭原则”,就必须坚持依赖倒转原则,否则不可能达到开-闭原则的要求。
  3. 合成/聚合复用原则:要尽量使用合成/聚合实现复用,而不是继承。遵守合成/聚合复用原则是实现开-闭原则的必要条件。
  4. 接口隔离原则:应当为客户端提供尽可能小的单独的接口,而不要提供大的总接口。这是对一个软件实体与其它软件实体的通信的限制。
  5. 迪米特法则:一个软件实体应当与尽可能少的其它实体发生相互作用。当一个系统功能扩展时,模块如果是孤立的,就不会影响到其他的对象。遵守迪米特法则的系统在功能需要扩展时,会相对容易地做到对修改的关闭。

实例

下面看一个开-闭原则的java例子:

3、里氏代换原则

概念

里氏代换原则是指所有引用基类(父类)的地方必须能透明的使用其子类的对象。即子类型必须能够替换掉它们的父类型。也就是说把父类都替换成它的子类,程序的行为没有发生变化。

里氏代换原则是继承复用的基础。只有当子类可以替换掉父类,软件单位的功能不受影响,父类才能真正被复用,而子类也能够在父类的基础上添加新的行为。

由于该原则子类型的可替换性使得父类类型的模块在无须修改的情况下就可扩展,所以满足里氏代换原则,餐恩公过满足开-闭原则。而依赖倒转原则中指出,依赖了抽象接口或抽象类,就不怕更改,原因也在于里氏代换原则。(这里可能听起来有点绕,但是多想想就能理顺了,或者看看下面的通俗说法)

里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。它包含以下4层含义:

  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
  • 子类中可以增加自己特有的方法。
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
  • 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

你可以直接这样想,凡是父类型存在的地方,子类替换掉父类,不会改变程序的行为。

例子

下面给出一个java例子。

4、依赖倒转原则

概念

要依赖于抽象,不要依赖于具体;高层模块不应该依赖于底层模块,两个都应该依赖抽象。

每一个逻辑实现都是由原子逻辑组成的,不可分割的原子逻辑即为底层模块,原子逻辑的再组装就是高层模块。

依赖倒转还可以表示为要针对接口编程,而非针对实现编程。

实例

下面给个例子理解一下。(结合例子理解更加印象深刻)

先看传统的例子:

此时,如果想要新增一个打开淘宝app的行为,则必须要在高层模块Phone类中添加openTaobao()方法,在底层模块新增一个Taobao类,并写出openTaobao方法,这样做在软

来源:小枫学IT

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年11月28日
下一篇 2020年11月28日

相关推荐