[设计模式之禅]六大原则

一、单一职责原则

单一职责原则的英文名称是single responsibility principle,简称SRP。单一职责原则就是类或接口内功能的单一化,降低之间的耦合度,增强程序的健壮。

书中总结单一职责原则的好处:

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

真要实现类的单一职责,这会引起类间耦合过重,类的数量增加等问题。所以类的单一职责确实受很多因素的制约,纯理论来讲,这个原则非常优秀,但是现实有现实的难处,要完全遵守很难做到。

书作者建议:接口一定要做到单一原则,类的设计尽量做到只有一个原因引起变化。

本章作者提到方法的单一职责,列举用户信息修改实例:用户信息修改功能要分解成用户名称修改,密码修改,地址修改三个功能,这样体现方法的单一职责原则。

但是实际项目中,存在可以同时修改用户名称,密码和地址的情况,这时该如何设计用户信息修改功能呢?

二、里氏替换原则

定义:英文缩写为LSP。所有引用基类的地方必须能透明的使用其子类的对象。通俗点讲,只要父类能出现的地方子类就能出现,而且替换为子类也不会产生任何错误或异常, 使用者可能根本就不需要知道是父类还是子类。但是,反过来就不行,有子类出现的地方,父类未必就能适应。

继承的优点:

  • 代码共享,减少创建类的工作量
  • 提高代码的重用性
  • 子类可以形似父类,但又异于父类
  • 提高代码的可扩展性
  • 提高产品或项目的 开放性

继承的缺点:

  • 继承是侵入性的。只要继承,就必须拥有父类的所有属性和方法
  • 降低代码的灵活性
  • 增加了耦合性。父类的常量,变量和方法被修改时,需要考虑子类的修改。

里氏替换原则为良好的继承定义了一个规范,一句简单的定义包含了4个层次。

  • 子类必须完全实现父类的方法

    注意:在类中调用其他类时务必要使用父类或接口,如果不能使用父类或接口,说明类的设计已经违背了LSP原则

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

  • 子类可以有自己的个性(在满足第一条前提下,可以扩展其他功能...)

  • 覆盖或实现父类的方法时输入参数可以被放大
  • 覆盖或实现父类的方法时输出结果可以被缩小

书作者建议:在项目中,采用里氏替换原则时,尽量避免子类的个性,一旦子类有个性,这个类和父类之间的关系很难被调和了,把子类当做父类使用,子类的个性被抹杀;把子类单独做一个业务来使用,则让代码间的耦合关系变的扑朔迷离--缺乏类替换的标准

三、依赖倒置原则

依赖倒置原则,Dependence Inversion Principle, DIP,包含三层含义:

  • 高层模块不应该依赖底层模块,两者都应该依赖于抽象
  • 抽象不应该依赖细节
  • 细节应该依赖抽象

依赖导致在JAVA中的表现是:

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

更精简的定义是面向接口编程(OOD - Object-Oriented Design)

依赖的三种写法:

  • 构造函数传递依赖对象

  • setter方法传递依赖对象

  • 在接口声明依赖对象,该方法叫做接口注入

书作者建议:

  • 每个类尽量都要有接口或抽象类,或者抽象类和接口同时具备
  • 变量的表面类型尽量使接口或抽象类
  • 任何类都不应该从具体类中诞生
  • 尽量不要覆盖基类的方法
  • 结合里氏替换原则使用

名词:开闭原则,对扩展开发,对修改关闭。

四、接口隔离原则

定义:建立单一接口,不要建立臃肿庞大的接口,通俗讲:接口尽量细化,同时接口中的方法计量少。

接口隔离原则与单一职责原则的区别?

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

接口隔离原则是对接口进行规范约束,其包含以下4层含义:

  • 接口要尽量小(根据接口隔离原则拆分接口时,首先必须满足单一职责原则)
  • 接口要高内聚

    什么事高内聚?高内聚就是提高接口、类、模块的处理能力,减少对外的交互。

  • 定制服务
  • 接口设计师有限度的

    接口的设计粒度越小,系统越灵活,这是不争的事实。但是,灵活的同时也带来了结构的复杂化,开发难度增加,可维护性降低,所以接口一定要适度,这个度要考靠经验和尝试判断...........................

书作者建议:

  • 一个接口只服务于一个子模块或业务逻辑
  • 通过业务逻辑压缩接口中的public方法
  • 已经被污染的接口,尽量去修改,若变更风险太大,则采用适配器模式转化处理
  • 了解环境,拒绝盲从。

五、迪米特法则

定义:Law of Demeter, LoD 也称为最少知识原则。

迪米特法则对类的低耦提出了明确的要求,包含以下4层含义:

  • 只和朋友交流

    什么叫直接朋友?两个对象之间的耦合叫朋友关系。

    注意,一个类只和朋友交流,不与 陌生类交流,不要出现getA().getB().getC().getD()这种情况,类与类之间的关系是建立在类间的,而不是方法间,因此一个方法尽量不引入一个类中不存在的对象。

  • 朋友间也是有距离的

    迪米特法则要求类“羞涩”一点,尽量不要对外公布太多的public方法和非静态的public变量,尽量内敛,多使用private, package-private, protected等访问权限

  • 是自己的就是自己的

    在实际应用中经常会出现这样一个方法:放在本类中也可以,放在其他类中也没有错,那怎么去 衡量呢?你可以坚持这样一个原则:如果一个方法放在本类中,既不增加类间关系,也对本类不产生负面影响,那就放置在本类中。

  • 谨慎使用Serializable

书作者建议:

迪米特法则的核心观点是类间解耦,弱耦合,只有弱耦以后,类的复用率才可以提高。

六、开闭原则

定义:一个软件实体如类,模块和函数应该对扩展开放,对修改关闭。

软件实体包括以下几部分:

  • 项目或软件产品中按照一定的逻辑规则划分的模块
  • 抽象和类
  • 方法
时间: 2024-10-11 07:04:28

[设计模式之禅]六大原则的相关文章

设计模式之禅--六大原则之开闭原则(精神领袖)

"对修改关闭,对拓展开放". 一个书店卖书的例子,见代码 public interface IBook { public String getName(); public int getPrice(); public String getAuthor(); } ---------- package com.sdkd.hms; public class NovelBook implements IBook { private String name; private int price;

【设计模式】对六大原则的宏观把控和微观细化

一天之前,终于将设计模式的第二遍看完了..在这两遍中,我又学到了很多知识.在之前看OOTV设计大赛时,总是提到面向对象设计的原则,这让我不明所以,直到看完整本书之后,才知道书中自有黄金屋..这篇文章主要写的就是面向对象设计的六大原则. 根据上图,我们可以轻松地得出,面向对象设计是以高内聚.低耦合为设计核心,抽象为基础,封装.继承和多态为特点.综合面向对象的原则.基础和特点,我们总结出了它的六大原则.通过这六大原则,我们还可以演化出多种设计模式..下面就写一下我对这六大原则的理解..      依

设计模式遵循的六大原则

Thinkphp中实现一些设计模式的方法 一.我们首先来了解一下设计模式所遵循的六大原则1.单一职责原则(1)定义:不要存在多于一个导致类变更的原因.通俗的说,即一个类只负责一项职责.(2)遵循单一职责原的优点有: 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多: 提高类的可读性,提高系统的可维护性: 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响.2.里氏替换原则 定义1:如果对每一个类型为 T1的对象

大话设计模式:(六大原则)

设计模式六大原则分别是单一职责原则(SPR).开放-封闭原则.里氏代换原则(LSP).依赖倒转原则.迪米特原则(LoD)和合成/聚合复用原则(CARP). 1.单一职责原则,就一个类而言,应该仅有一个引起它变化的原因. 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力.这种耦合导致的设计,当变化发生时,设计会遭受到意想不到的破坏. 软件设计真正要做的许多内容,就是如果发现职责并把那些职责相互分离.其实这个要去判断是否应该分离出类来,也

Java设计模式之——面向对象六大原则

面向对象六大原则: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):开闭原则 设计模式六大原则(3):里氏替换原则 设计模式六大原则(4):依赖倒置原则 设计模式六大原则(5):接口隔离原则 设计模式六大原则(6):迪米特原则 设计模式六大原则(1):单一职责原则 单一职责原则的英文名称是 Single Responsibility Principle,缩写为 SRP.SRP 的定义是:就一个类而言,应该仅有一个引起它变化的原因.简单来说,一个类中应该是一组相关性很高的函数.数据的

【设计模式】漫谈六大原则

六大原则的起因:面向对象中封装.继承.多态三大支柱蕴含了用抽象来封装变化,降低耦合,实现复用的精髓. 封装:隐藏内部实现,保护内部信息. 继承:实现复用,归纳共性. 多态:改写对象行为,实现更高级别的继承. 要实现这些目的,就必须遵守一些原则:封装变化.对接口编程.少继承多聚合等等总结这些,归纳出六大原则 单一职责原则(SRP) 定义:就一个类而言,应该仅有一个引起它变化的原因. 翻译:一个类只有一个职责. 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这

设计模式之禅--六大设计原则之接口隔离原则

设计模式就是让我们更方便的解决问题. 这里分享一个故事.我有一个朋友,嗯没错就是一个朋友,参加一个软件比赛,一个同学写服务器上的代码,三天两头更新,丝毫不考虑写客户端的人的感受,简直不能再牛.如果Java的更新有这么一次,没有考虑在不影响以前代码的基础上做修改,得有多少程序员吐血身亡. 接口隔离原则的定义: 建立单一接口,不要建立臃肿放大的接口.接口尽量细化,同时接口中的方法尽量少. 这不是单一职责原则,单一职责要求的是类和接口的职责单一,注重的是职责,这是业务逻辑上的划分,而借口隔离原则要求接

设计模式之禅--六大设计原则之迪米特原则

定义: 一个对象应该对其他对象有最少的了解 它包含以下四层定义 只和朋友交流 朋友类的定义是这样的:出现在成员变量.方法的输入输出函数中的类成为成员朋友类,而出现在方法体内部的类不属于朋友类. 我吧书上的例子简化了一下: A让B去数有多少个C A让B去数有多少个C public class A{ public void command(B b){ List<C> lists = new List<C>(); for(int i = 0; i < 10; ++i){ list.

初探设计模式六大原则

前言 我想用贴近生活的语句描述一下自己对六种原则的理解.也就是不做专业性的阐述,而是描述一种自己学习后的理解和感受,因为能力一般而且水平有限,也许举的例子不尽妥当,还请谅解 原本我是想用JavaScript编写的,但是JavaScript到现在还没有提出接口的概念,而用TypeScript写又感觉普及度还不算特别高,所以还是决定用Java语言编写 目录 设计模式有六大原则 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特原则 开闭原则 首先要提的是:六大原则的灵魂是面向接口,以及如