设计原则之 SOLID 原则
以下是在极客时间《设计模式之美》 中的写学习笔记与心得的总结
在最初开始学设计模式的时候,总觉的要学的是那23种经典的设计模式。通过一段的学习,才突然领悟,设计原则才是王道,才是真正的内功心法,设计模式是招式,只有会心法,才能用好招式。
在这里总结下常用的几种设计原则:SOLID、KISS、YAGNI、DRY、LOD
SOLID 原则
SOLID 原则的对应五种设计原则,每个首字母对应一种
- S:单一职责原则
- O:开闭原则
- L:里氏替换原则
- I:接口隔离原则
- D:依赖反转原则
SRP 单一职责原则
单一职责原则(Single Responsibility Principle):一个类或者模块只负责完成一个职责(或者功能)
A class or module should have a single responsibility
对类和模块的理解:
- 第一种理解是:把模块看做比类更抽象的概念,类也可以看做模块
- 第二种理解是:把模块看做比类更加粗粒度的代码块,模块中包含了多个类,多个类组成一个模块。
除了类和模块,在编写方法的时候,也应该考虑单一职责原则,因为函数才是功能执行的最小单元,细微处做好单一职责。
在写代码的过程中,一个类只负责完成一个职责或者功能。不要设计大而全的类,要设计粒度小、功能单一的类。单一职责原则是为了实现代码高内聚、低耦合,提高代码的复用性、可读性、可维护。
如何判断类的职责是否足够单一?
不同的应用场景、不同阶段的需求背景、不同的业务层面,对同一个类的职责是否单一,可能会有不同的判定结果。实际上,一些侧面的判断指标更具有指导意义和可执行性,比如,出现下面这些情况就有可能说明这类的设计不满足单一职责原则:
- 类中的代码行数、函数或者属性过多。(该考虑做拆分)
- 类依赖的其他类过多。或者依赖类的其他类过多;(耦合度过高)
- 私有方法过多
- 比较难给类起一个合适的名字;(类可能大而杂)
- 类中大量方法都是集中操作类中的某几个属性;
类的职责也不是越单一越好
单一职责原则通过避免设计大而全的类,避免将不相关的功能耦合在一起,来提高类的内聚性。同时,类职责单一,类依赖的和被依赖的其他类也会变少,减少了代码的耦合性,以此来实现代码的高内聚、低耦合。但是,如果拆分得过细,实际上会适得其反,反倒会降低内聚性,也会影响代码的可维护性。
OCP 开闭原则
开闭原则(Open Closed Principle):软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”
software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification.
换句话说就是,在后期维护代码或者实现新需求的时候,尽可能在原有的基础上添加代码,而不是去修改已有代码来实现需求。因为这样不会印象之前的程序的正确性,可在最小改动下完成需求。
目的:对拓展开放是为了应对变化(需求),对修改关闭是为了保证已有代码的稳定性;最终结果是为了让系统更有弹性!最终提高代码的可维护性、可扩展性。
注意:修改代码并不意味着违背开闭原则
开闭原则的初衷:只要它没有破坏原有的代码的正常运行,没有破坏原有的单元测试,我们就可以说,这是一个合格的代码改动。
软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。从定义中,我们可以看出,开闭原则可以应用在不同粒度的代码中,可以是模块,也可以类,还可以是方法(及其属性)。同样一个代码改动,在粗代码粒度下,被认定为“修改”,在细代码粒度下,又可以被认定为“扩展”。
如何做到对扩展开放、对修改关闭?
我们要时刻具备扩展意识、抽象意识、封装意识。在写代码的时候,多花点时间思考一下,这段代码未来可能有哪些需求,如何设计代码结构,实现留好扩展点,以便在未来需求变更的时候,在不改动代码整体结构、做到最小代码改动的情况下,将新的代码灵活地插入到扩展点上。
很多设计原则、设计思想、设计模式,都是以提高代码的扩展性为最终目的的。特别是 23 种经典设计模式,大部分都是为了解决代码的扩展性问题而总结出来的,都是以开闭原则为指导原则的。最常用来提高代码扩展性的方法有:多态、依赖注入、基于接口而非实现编程,以及大部分的设计模式(比如,装饰、策略、模板、职责链、状态)。
LSP 里式替换原则
里式替换原则(Liskov Substitution Principle):子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。
If S is a subtype of T, then objects of type T may be replaced with objects of type S, without breaking the program。
里式替换原则是用来指导,继承关系中子类该如何设计的一个原则。理解里式替换原则,最核心的就是理解“design by contract,按照协议来设计”这几个字。父类定义了函数的“约定”(或者叫协议),那子类可以改变函数的内部实现逻辑,但不能改变函数原有的“约定”,因为如果违反父类的约点,在用子类替换父类的时候程序可能会出错。
这里的约定包括:
- 函数声明要实现的功能;(这是前提)
- 对输入、输出、异常的约定;(如果违反这些,子类替换父类的时候,IDE 首先会报错)
- 甚至包括注释中所罗列的任何特殊说明。(注释中肯能有前人的趟过的坑,或者挖的坑,哈哈,如果有坑没注释,就只能自己趟)
ISP 接口隔离原则
接口隔离原则(Interface Segregation Principle):客户端不应该强迫依赖它不需要的接口。客户端可以理解为接口的调用者。
Clients should not be forced to depend upon interfaces that they do not use。
对于“接口”,可以理解为三种东西:
- 一组 API 接口集合
- 单个 API 接口或函数
- OOP 中接口的概念
如果把接口理解为 一组 API 接口集合
:ISP 代表,我们在设计微服务接口或 类库时,如果部分接口只被部分调用者使用,那就需要将这部分接口隔离出来,单独给对应的调用者使用,而不是强迫其他调用者也依赖这部分不会被使用的接口。
把接口理解为 单个 API 接口或函数
:ISP 代表 函数的设计功能要单一,不要将多个不同的功能逻辑在一个一函数中实现。
把接口理解OOP 中的接口
:ISP 则也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口的实现类和调用者,依赖不需要的接口函数。
DIP 依赖反转原则
依赖反转原则(Dependency Inversion Principle):高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。
High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.
所谓高层模块和底层模块是指:在调用链上,调用者属于高层,被调用者属于底层。
个人感觉这个原则是最魔幻的,如 我们的Java web 程序,写好打包后,放在 Tomcat 中就可以运行。这里 Tomcat 没有一行代码是调用我们写的代码的,但它可以运行我们的代码。
设计原则之 SOLID 原则相关推荐
- 面向对象设计的七大原则 (包括SOLID原则)
文章目录 概述 1. 单一原则 2. 里氏替换原则 3. 依赖倒转原则 4. 接口分隔原则(Interface Segregation Principle ,ISP) 5. 迪米特法则 (Law of ...
- 面向对象的程序设计原则之SOLID原则
Ò程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特•C•马丁在21世纪早期 引入的记忆术首字母缩略字,指代了面向对象编程和面向对象设计的五个基本原则.当这些 ...
- 【编程素质】设计模式原则(SOLID原则)
设计模式的使用并不一定会提升效率,我们需要根据实际情况来判断是否需要使用设计模式.在很多时候,只要遵循这些OO原则来写代码,也相当于使用了设计模式.毕竟设计模式就是根据这些OO原则形成的一套规范. 1 ...
- [设计模式]设计模式SOLID原则
在程序设计领域, SOLID(单一功能.开闭原则.里氏替换.接口隔离以及依赖倒置)是由罗伯特·C·马丁在21世纪早期引入的记忆术首字母缩略字,指代了面向对象编程和面向对象设计的五个基本原则.当这些原则 ...
- 什么是SOLID原则(第1部分)
翻译自:What's the deal with the SOLID principles?(part 1) 即使你是一个初级开发人员,你也可能听说过 SOLID 原则.它们无处不在.工作面试时,你也 ...
- 【译】浅谈SOLID原则
SOLID原则是一种编码的标准,为了避免不良设计,所有的软件开发人员都应该清楚这些原则.SOLID原则是由Robert C Martin推广并被广泛引用于面向对象编程中.正确使用这些规范将提升你的代码 ...
- SOLID原则:解释和实例
在面向对象编程中,SOLID是5个重要的设计原则的缩写.首先是由著名的软件大师Robert C.Martin (Bob 大叔)在Design Principles and Design Pattern ...
- SOLID原则-依赖倒置原则
简介 前面我们已经介绍了 SRP ,单一职责原则 OCP,开闭原则 LSP,里式替换原则 ISP,接口隔离原则 今天来详解依赖倒置原则. 作为一个Java程序员,你可能听说过代码耦合以及被告知应避免代 ...
- 面向对象设计的重要原则:SOLID
SOLID是面向对象设计5大重要原则的首字母缩写: 1.单一职责原则(SRP) 2.开放封闭原则(OCP) 3.里氏替换原则(LSP) 4.接口隔离原则(ISP) 5.依赖倒置原则(DIP) 下面具体 ...
最新文章
- python实现三叉树_使用python代码实现三叉搜索树高效率”自动输入提示”功能
- springboot学习笔记(八)
- mysql insert 主键冲突_insert 时防止出现主键冲突错误的方法
- Start Instance 操作详解 - 每天5分钟玩转 OpenStack(31)
- 【动态规划】 数字游戏 (ssl 1653)
- python 百分比数据_如何使用python计算数据列相对于另一列的百分比排名
- AfxMessageBox
- Cisdem PDFMaster for Mac(PDF批量转换工具)
- 如何在虚拟机中安装wp8的sdk,无法启动模拟器问题
- 大智慧专业财务数据服务器文件,大智慧财务数据指标公式
- 大数据分析师的报考条件是什么?
- 克隆出错fatal: unable to access ‘https://github.com/‘: OpenSSL SSL_connect:
- 让机器辨别气味:利用图神经网络预测分子的嗅觉属性
- 计算机术语死机,计算机“死机”故障原因及处理办法大全
- ubuntu更新过程中出现错误:校验数字签名时出错。此仓库未被更新,下列签名无效
- 暑假训练 The Triangle Game (OpenJ_Bailian - 1574)
- 谷歌和IE的兼容问题
- jq 移动端网页分享功能_js实现QQ、微信、新浪微博分享功能
- 用HBuilder X编辑器打开的网页出现中文乱码
- 第十七周 项目6.1 求出每名同学的总分和均分