【设计模式】二、面向对象设计原则概述

系列文章|源码

https://github.com/tyronczt/design-mode-learn

概述

软件项目中,需求是不断变化的,需求也是项目中最难把控的,需求的变更也是无法避免的。我们写的软件程序,如何能实现拥抱变化,使我们的软件达到 可维护 和 可复用 ,这是一代代软件工程师不断追寻的真理。

导致一个软件的可维护性较低的原因有四个:

  1. 过于僵硬(Rigidity)

很难在一个软件系统里加入新的特性,一旦加入新的特性就会影响到其他模块的功能,最后会变成跨越几个模块的改动,由于设计上的缺陷,导致不敢轻易往原有的系统中添加新的特性的僵硬化的情况。

  1. 过于脆弱(Fragility)

与过于僵硬同时存在。对一个地方的修改,往往会导致看起来没有什么关系的另一个地方发生故障,尽管在修改前,设计师会竭尽所能预测可能的故障点,但是在修改完成之前,系统的原始设计师甚至都无法预测到可能会波及的地方,这种一碰就碎的情况,就是软件系统过于脆弱。

  1. 复用率低(Immobility)

所谓复用,就是指一个软件的组成部分,可以在一个项目的不同地方甚至不同的项目中重复使用。每当程序员发现一段代码、函数、模块的功能可以在新模块或者新系统中使用,但是发现这些现存的代码、函数、模块依赖于一大堆其他的东西,以至于很难将他们分开。最后,他们发现最好的办法就是不去碰这些东西,而是重写自己的代码。

这样的系统存在复用率低的问题。

  1. 黏度过高(Viscosity)

对系统的改动可以采取保存原始设计意图和设计框架的方式,也可以以破坏原始意图和框架的方式进行。前者对系统未来有利,而后者是权宜之计,可以解决短期问题,但会牺牲中长期利益。如果一个系统设计,总是使得第二种办法比第一种容易,就叫黏度过高。

一个好的系统设计应该具备如下性质:

  1. 可扩展性(Extensibility)

新的特性很容易加入到系统中去,就是可扩展性,就是“过于僵硬”反面。

  1. 灵活性(Flexibility)

可以允许代码修改平稳地发生,而不会波及到很多其他的模块。灵活性就是“过于脆弱”的反面。

  1. 可插入性(Pluggability)

可以很容易的将一个类抽出去,同时将一个有同样接口的类加入进来,这就是可插入性。

提高系统可维护性和可复用性的设计原则

面向对象设计原则为支持可维护性复用而诞生,这些原则蕴含在很多设计模式中,它们是从许多设计方案中总结出的指导性原则。面向对象设计原则也是我们用于评价一个设计模式的使用效果的重要指标之一。

单一职责原则(Single Responsibility Principle, SRP)

一个类只负责一个功能领域中的相应职责

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

软件实体应对扩展开放,而对修改关闭

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

所有引用基类对象的地方能够透明地使用其子类的对象

依赖倒转原则(Dependence Inversion Principle, DIP)

抽象不应该依赖于细节,细节应该依赖于抽象

接口隔离原则(Interface Segregation Principle, ISP)

使用多个专门的接口,而不使用单一的总接口

合成复用原则(Composite Reuse Principle, CRP)

尽量使用对象组合,而不是继承来达到复用的目的

迪米特法则(Law of Demeter, LoD)

一个软件实体应当尽可能少地与其他实体发生相互作用

软件的可复用性

复用的重要性

较高的生产率,较高的软件质量,恰当的复用可以改善系统的可维护性。

传统的复用

代码的剪贴复用,算法的复用,数据结构的复用。

面向对象的设计的复用

面向对象的语言中,数据的抽象化、继承、封装和多态的特性是几项最重要的语言特性,这些特性使得一个系统可以在更高的层次上提供可复用性。数据的抽象化和继承可以使得概念和定义得以复用,多态性使得实现和应用可以复用,而抽象化和封装可以保持和促进系统的可维护性。这样,复用的焦点不再集中在函数、算法等具体的实现细节上,而是集中在最重要的具有宏观商业逻辑的抽象层次上。

抽象层是一个应用系统做战略性判断和决定的地方,那么抽象层次应当是较为稳定的,应当是复用的重点。如果抽象层次的模块相对独立于具体层次的模块,那么具体层次的变化不会影响到抽象层次的,所以抽象层次模块的复用会比较容易。

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

对可维护性的支持

首先,适当地提高系统的可复用性,可以提高系统的可扩展性。允许一个具有同样接口新类代替旧的类,是对抽象接口的复用。客户端依赖于一个抽象的接口,而不是一个具体的实现类,使得这个具体的类可以被其他的类取代,而不需要修改客户端的代码。

系统的可扩展性是由开闭原则里氏代换原则依赖倒转原则合成复用原则实现的。

其次,适当地提高系统的可复用性,可以提高系统的灵活性。在一个设计得当的系统中,每一个模块都相对于其他模块独立存在,并且保持与其他模块尽可能少的通信。这样一来,在其中一个模块的代码发生修改的时候,这个修改的压力不会传递到其他模块。

系统的灵活性是有开闭原则迪米特法则接口隔离原则保证的。

最后,适当地提高系统的可复用性,可以提高系统的可插入性,在一个符合“开-闭“原则的系统中,抽象层封装了与商业逻辑有关的重要行为,这些行为的具体实现由实现层给出。当一个实现类再满足需要,需要以另一个实现类取代的时候,系统的设计就可以保证旧的类可被拔出,新类可以被插入。

可插入性开闭原则里氏代换原则合成复用原则依赖倒转原则保证。

参考

面向对象设计的七大原则

软件的可维护性和可复用性

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,588评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,456评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,146评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,387评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,481评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,510评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,522评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,296评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,745评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,039评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,202评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,901评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,538评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,165评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,415评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,081评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,085评论 2 352

推荐阅读更多精彩内容