设计模式六大原则(SOLID)

S ->Single Responsibility Principle 单一职责原则

应该有且仅有一个原因引起类的变更。

好处

  • 类的复杂性降低,实现什么职责都有清晰明确的定义;
  • 可读性提高,复杂性降低,那当然可读性提高了;
  • 可维护性提高,可读性提高,那当然更容易维护了;
  • 变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护性都有非常大的帮助。

注意: 单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因环境而异。单一职责适用于接口、类,同时也适用于方法。
建议:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

O ->Open Closed Principle 开闭原则

一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
软件实体包括
● 项目或软件产品中按照一定的逻辑规则划分的模块
● 抽象和类
● 方法

好处

  • 减轻重新测试的压力:新增加的类,新增加的测试方法,只要保证新增加类是正确的就可以了。
  • 开闭原则可以提高复用性:缩小逻辑粒度,直到一个逻辑不可再拆分为止。
  • 开闭原则可以提高可维护性

注意: 注意 开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段。
建议:放弃修改历史的想法,一个项目的基本路径应该是这样的:项目开发、重构、测试、投产、运维,其中的重构可以对原有的设计和代码进行修改,运维尽量减少对原有代码的修改,保持历史代码的纯洁性,提高系统的稳定性。
运用
抽象约束:通过接口或抽象类可以约束一组可能变化的行为,并且能够实现对扩展开放

  • 通过接口或抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法
  • 参数类型、引用对象尽量使用接口或者抽象类,而不是实现类
  • 抽象层尽量保持稳定,一旦确定即不允许修改

元数据(metadata)控制模块行为,减少重复开发
例如:Spring容器,SpringContext配置文件
制定项目章程: 对项目来说,约定优于配置
封装变化

  • 将相同的变化封装到一个接口或抽象类中;
  • 将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。

L ->Liskov Substitution Principle 里氏替换原则

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

四层含义:

  1. 子类必须完全实现父类的方法
    注意: 如果子类不能完整地实现父类的方法,或者父类的某些方法在子类中已经发生“畸变”,则建议断开父子继承关系,采用依赖、聚集、组合等关系代替继承。

  2. 子类可以有自己的个性
    即有子类出现的地方父类未必就可以出现

  3. 覆盖或实现父类的方法时输入参数可以被放大

  4. 覆写或实现父类的方法时输出结果可以被缩小
    此处复习重写原则

    • 重写方法不能比被重写方法限制有更严格的访问级别
    • 参数列表必须与被重写方法的相同
    • 返回类型必须与被重写方法的返回类型相同,或是子类(子类的返回值也为父类返回值的子类)
    • 重写方法不能抛出新的异常或者比被重写方法声明的检查异常更广的检查异常。但是可以抛出更少,更有限或者不抛出异常
    • 不能重写被标识为final的方法
    • 如果一个方法不能被继承,则不能重写它。如private方法(注意:继承可以继承父类private方法,只是没办法使用)

继承的优点:

  • 代码共享,减少创建类的工作量,每个子类都拥有父类的方法和属性;
  • 提高代码的重用性
  • 子类可以形似父类,但又异于父类
  • 提高代码的可扩展性 比如:扩展接口都是通过继承父类来完成的
  • 提高产品或项目的开放性

缺点:

  • 继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法;
  • 子类必须拥有父类的属性和方法,降低代码的灵活性。
  • 增强了耦合性。

L ->Law of Demeter(Least Knowledge Principle) 迪米特法则(最少知识原则)

一个类应该对自己需要耦合或调用的类知道得最少

  1. 只和朋友交流
    一个类只和朋友交流,不与陌生类交流,不要出现getA().getB().getC().getD()这种情况(在一种极端的情况下允许出现这种访问,即每一个点号后面的返回类型都相同),类与类之间的关系是建立在类间的,而不是方法间,因此一个方法尽量不引入一个类中不存在的对象,当然,JDK API提供的类除外。
  2. 朋友间也是有距离的
    一个类公开的public属性或方法越多,修改时涉及的面也就越大,变更引起的风险扩散也就越大。为了保持朋友类间的距离,在设计时需要反复衡量:尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private、package-private、protected等访问权限。
  3. 是自己的就是自己的
    如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中
  4. 谨慎使用Serializable

I ->Interface Segregation Principle 接口隔离原则

接口尽量细化,同时接口中的方法尽量少。
注意:单一职责的审视角度是不相同的,单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划分,而接口隔离原则要求接口的方法尽量少。

接口分为两种:
实例接口(Object Interface),在Java中声明一个类,然后用new关键字产生一个实例,它是对一个类型的事物的描述,这是一种接口。(就是普通类对象)
类接口(Class Interface),Java中经常使用的interface关键字定义的接口。

四层含义:

  1. 接口要尽量小
    根据接口隔离原则拆分接口时,首先必须满足单一职责原则
  2. 接口要高内聚
    要求在接口中尽量少公布public方法
  3. 定制服务
    定制服务就是单独为一个个体提供优良的服务。比如:应对不同的访问提供不同的接口
  4. 接口设计是有限度的
    灵活的同时也带来了结构的复杂化,开发难度增加,可维护性降低
    运用
    一个接口只服务于一个子模块或业务逻辑
    通过业务逻辑压缩接口中的public方法
    已经被污染了的接口,尽量去修改,若变更的风险较大,则采用适配器模式进行转化处理
    了解环境,拒绝盲从。

D ->Dependence Inversion Principle 依赖倒置原则(面向接口编程)

模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的;
接口或抽象类不依赖于实现类;
实现类依赖接口或抽象类。

好处:可以减少类间的耦合性,提高系统的稳定性,降低并行开发引起的风险,提高代码的可读性和可维护性。
三种写法:

  1. 构造函数传递依赖对象
  2. Setter方法传递依赖对象
  3. 接口声明依赖对象

运用:

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

推荐阅读更多精彩内容

  • 设计模式六大原则 设计模式六大原则(1):单一职责原则 定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类...
    viva158阅读 765评论 0 1
  • 转载标注声明:http://www.uml.org.cn/sjms/201211023.asp 目录:[设计模式六...
    Bloo_m阅读 707评论 0 7
  • 转载自 设计模式六大原则[http://www.uml.org.cn/sjms/201211023.asp#3] ...
    厨子阅读 1,089评论 2 5
  • 设计模式六大原则(1):单一职责原则 定义:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。 ...
    Jabir_Zhang阅读 643评论 0 3
  • 单一职责原则 (SRP) 全称 SRP , Single Responsibility Principle 单一职...
    米莉_L阅读 1,761评论 2 5