一文get到SOLID原则的重点
最近没事再次翻开《敏捷软件开发:原则、模式与实践》看,发现以前似懂非懂的东西突然就看懂了,get到了讲的重点。
SOLID(单一职责原则、开放—封闭原则、里氏替换原则、接口隔离原则以及依赖倒置原则)是由罗伯特·C·马丁引入,成为了面向对象设计中的五个基本原则。当这些原则被一起应用时,它们使得一个程序员开发一个容易进行软件维护和扩展的系统变成可能。
1 单一职责原则(SRP)
定义:一个类应该只有一个发生变化的原因
为何把这两个职责分离到分离到单独的类中很重要呢?因为每一个职责都是变化的一个轴线。当需求变化时,该变化会反映为类的职责变化。如果一个类承担了多于一个的职责,那么引起它变化的原因就会有多个。如果一个类承担的职责过多,就等于把职责耦合在了一起。一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意向不到的破坏。
在SRP中,我们把职责定义为变化的原因,如果你能够想到多于一个的动机去改变一个类,这个类就具有多于一个的职责。有时,我们很难注意到这一点。我们习惯于以组的形式去考虑职责。
仅当变化发生时,变化的轴线才具有实际意义。如果没有征兆,那么应用SRP或者任何其他原则都是不明智的。
软件设计真正要做的许多工作,就是发现职责并把那些职责相互分离。其余原则都会以这样或者那样的方式回到这个问题上。
2 开放封闭原则(OCP)
定义:软件实体(类、模块、函数等)应该是可以扩展的,但是不可修改。
如果程序中的一处改动就会产生连锁反应,导致一系列相关模块的改动,那么设计就具有僵化性的臭味。OCP建议我们应该对系统进行重构,这样以后对系统再进行那样的改动时,就不会导致更多的修改。如果正确地应用OCP,那么以后进行同样的改动时,就只需要添加新的代码,而不必改动已经正常运行的代码。
怎样可能在不改动模块源代码的情况下去更改它的行为呢?如果不更改一个模块,又怎么能够去更改它的功能呢?答案就是抽象。
策略模式(STARTEGY)和模板方法(TEMPLATE METHOD)模式是满足OCP最常用的方法。应用它们,可以把一个功能的通用部分和实现细节部分清晰的分离开来。
在许多方面,OCP都是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处:灵活性、可重用性、以及可维护性。开发人员应该仅仅对程序中呈现出频繁变化的那些部分做出抽象。拒绝不成熟的抽象和抽象本身一样重要。
3 里氏替换原则(LSP)
定义:子类型必须能够替换掉它们的基类型。
LSP得出一个非常重要的结论:一个模型如果孤立的看,并不具有真正意义的有效性。模型的有效性只能通过它的客户程序来表现。
LSP基于契约的设计(Design By Contract,DBC)。使用DBC类的编写者显示地规定针对该类的契约。客户代码的编写者可以通过该契约获悉可以依赖的行为方式。契约是通过为每个方法声明前置条件和后置条件来指定的。要使一个方法得以执行,前置条件要为真。执行完毕后,该方法的后置条件为真。派生类的行为方式和输出不能违反基类已经确立的任务限制,基类的用户不应该被派生类的输出扰乱。
OCP是OOD(面向对象设计)中很多说法的核心。如果这个原则应用得有效,应用程序就会具有更强的可维护性、可重用性以及健壮性。LSP是使OCP成为可能的主要原则之一。正是子类型的可替换性才使得使用基类型表示的模块在无需修改的情况下可以扩展。这种可替换性必须是开发人员可以隐式依赖的。这样如果没有在代码中显式地支持基类型的契约,那么就必须很好地、广泛地理解这些契约。子类型正确的定义是可替换的,可替换性通过隐式或者显式的契约来定义。
4 接口隔离原则(ISP)
定义:不应该强迫客户程序依赖并未使用的方法。
这个原则用来处理“胖”接口所存在的缺点。如果类的接口不是内聚(内聚(Cohesion)是一个模块内部各成分之间相关联程度的度量)的,就表示该类具有“胖”接口。
如果强迫客户程序依赖那些不使用的方法,那么这些客户程序就面临着由于这些未使用的方法的改变所带来的变更。这无意中导致了所有客户程序之间的耦合。换言之,如果一个客户程序依赖于一个含有它不使用的方法的类,但是其他客户却确实要用这个方法,那么当其实客户要求这个类改变时,就会影响到这个客户程序。分离客户就是分离接口。
客户程序应该仅仅以来于它们实际调用的方法。通过把胖类接口分解为多个特定于客户程序的接口,可以实现这个目标。每个特定于客户程序的接口仅仅声明它的特定客户或者客户组调用的那些函数。接着,该胖类就可以继承所有特定于客户程序的接口,并实现它们,这就解除了客户程序和没有调用的方法间的依赖关系,并使客户程序之间互不依赖。
5 依赖倒置原则(DIP)
定义:
a.高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
b.抽象不应该依赖于细节。细节应该依赖于抽象。
该原则是框架设计的核心原则。
倒置的含义
为什么使用"倒置”,倒置是较于传统的软件开发,比如结构化分析和设计,总是倾向于创建一些高层模块依赖于低层模块、策略依赖于细节的软件结构。一个设计良好的面向对象的程序,其依赖程序结构相对于传统的过程式方法设计的通常结构而言就是被“倒置"了。
倒置的是什么?
DIP不仅仅是依赖关系的倒置,它也是接口所有权的倒置。客户拥有接口所有权,而它们的服务者则从这些接口派生。
由客户模块或者层来声明它们所需要的服务接口,那么仅当客户需要时才会对接口改变。这样改变实现抽象接口的类就不会影响到客户。
层次化:
所有结构良好的面向对象架构都具有清晰的层次定义,每个层次通过定义一个良好的、受控的接口向外提供了一组内聚的服务。
面象对象的程序设计倒置了依赖关系,使得细节和策略依赖于抽象,并且常常是客户拥有服务接口。依赖关系的倒置正是好的面向对象设计的标志所在。是实现许多面向对象技术所宣称的好处的基本低层机制。它的正确应用对于创建重用的框架来说是必需的。同时它对于构建在变化面前富有弹性也是重要的。由于抽象和细节彼此隔离,所以代码也非常容易维护。
相关阅读
一文get到SOLID原则的重点的更多相关文章
- 超易懂!原来SOLID原则要这么理解!
说到 SOLID 原则,相信有过几年工作经验的朋友都有个大概印象,但就是不知道它具体是什么.甚至有些工作了十几年的朋友,它们对 SOLID 原则的理解也停留在表面.今天我们就来聊聊 SOLID 原则以 ...
- 浅谈 SOLID 原则的具体使用
SOLID 是面向对象设计5大重要原则的首字母缩写,当我们设计类和模块时,遵守 SOLID 原则可以让软件更加健壮和稳定.那么,什么是 SOLID 原则呢?本篇文章我将谈谈 SOLID 原则在软件开发 ...
- 【转】面向对象设计的SOLID原则
S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写. SRP The Single Responsibility ...
- 面向对象设计的SOLID原则
S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则(Programming Priciple)的首字母缩写. SRP The Single Responsibility ...
- SOLID 原则
世纪的前几年里,“ Uncle Bob”Robert Martin 引入了用OOP 开发软件的五条原 则,其目的是设计出更易于维护的高质量系统.无论是设计新应用程序,还是重构现有基 本代码,这些 S ...
- 面向对象涉及SOLID原则
S = Single Responsibility Principle 单一职责原则 O = Opened Closed Principle 开放闭合原则 L = Liscov Substituti ...
- TypeScript 中的 SOLID 原则
下面的文章解释了正确使用 TypeScrip的 SOLID原则. 原文地址:https://samueleresca.net/2016/08/solid-principles-using-typesc ...
- 类设计的SOLID原则
SOLID原则是面向对象范式的核心 单一职责原则(Single Responsible Principle, SRP):对于一个类,应该仅有一个引起它变化的原因.其基础是内聚,表示类完成单一功能的程度 ...
- 面向对象的SOLID原则白话篇
面向对象的SOLID原则 简介 缩写 全称 中文 S The Single Responsibility Principle 单一责任原则 O The Open Closed Principle 开放 ...
随机推荐
- 领域驱动模型DDD(二)——领域事件的订阅/发布实践
前言 凭良心来说,<微服务架构设计模式>此书什么都好,就是选用的业务过于庞大而导致代码连贯性太差,我作为读者来说对于其中采用的自研框架看起来味同嚼蜡,需要花费的学习成本实在是过于庞大,不仅 ...
- GEOS 使用记录
GEOS 使用记录 官网 https://trac.osgeo.org/geos/ https://libgeos.org/ 下载地址 https://libgeos.org/usage/downlo ...
- 【直播回顾】OpenHarmony知识赋能第四期第二课——GPIO驱动开发
3月17日晚上19点,知识赋能第四期直播的第二节课<OpenHarmony标准系统HDF框架之GPIO驱动开发>,在OpenHarmony开发者成长计划社群内成功举办. 本期课程,由 ...
- AcWing 165. 小猫爬山 DFS
165. 小猫爬山 https://www.acwing.com/problem/content/description/167/ 题目 思路 dfs每一个小猫,对于要不要开新车的状态再进行dfs(注 ...
- 【Azure 应用服务】Azure Function 启用 Managed Identity后, Powershell Funciton出现 ERROR: ManagedIdentityCredential authentication failed
问题描述 编写Powershell Function,登录到China Azure并获取Azure AD User信息,但是发现遇见了 [Error] ERROR: ManagedIdentityCr ...
- 配置Docker镜像源为国内镜像源
镜像加速 /etc/docker/daemon.json 没有这个文件 创建这个文件 vi /etc/docker/daemon.json 按 i 进行插入 { "registry-mirr ...
- 开发一个不需要重写成Hive QL的大数据SQL引擎
摘要:开发一款能支持标准数据库SQL的大数据仓库引擎,让那些在Oracle上运行良好的SQL可以直接运行在Hadoop上,而不需要重写成Hive QL. 本文分享自华为云社区< ...
- 图解 Git 工作原理
此页图解 git 中的最常用命令.如果你稍微理解git的工作原理,这篇文章能够让你理解的更透彻. 基本用法 上面的四条命令在工作目录.暂存目录(也叫做索引)和仓库之间复制文件. git add fil ...
- Django基础之Form和ModelForm组件
https://www.cnblogs.com/clschao/articles/10486468.html 1.创建django项目 2.创建py文件 3.导入form from django im ...
- 常见排序算法的golang 实现
五种基础排序算法对比 五种基础排序算法对比 1:冒泡排序 算法描述 比较相邻的元素.如果第一个比第二个大,就交换它们两个: 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素 ...