简单总结下SOLID 原则

SOLID 原则并非单纯的 1 个原则,而是由 5 个设计原则组成的,它们分别是:单一职责原则、开闭原则、里式替换原则、接口隔离原则和依赖反转原则,依次对应 SOLID 中的 S、O、L、I、D 这 5 个英文字母。

单一职责原则

单一职责原则的英文是 Single Responsibility Principle,缩写为 SRP。这个原则的英文描述是这样的:A class or module should have a single responsibility。如果我们把它翻译成中文,那就是:一个类或者模块只负责完成一个职责(或者功能)。

一个类只负责完成一个职责或者功能。也就是说,不要设计大而全的类,要设计粒度小、功能单一的类。换个角度来讲就是,一个类包含了两个或者两个以上业务不相干的功能,那我们就说它职责不够单一,应该将它拆分成多个功能更加单一、粒度更细的类。

比如我写了一个user的类,后面我把第三方登录信息也放进来了,那这个类就冗余了,应该把第三方登录信息放到另外一个表里。

 

开闭原则

开闭原则的英文全称是 Open Closed Principle,简写为 OCP。它的英文描述是:software entities (modules, classes, functions, etc.) should be open for extension , but closed for modification。我们把它翻译成中文就是:软件实体(模块、类、方法等)应该“对扩展开放、对修改关闭”。

添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

我个人的理解是代码写完后,后续添加新功能的时候不会动到原来的代码,这种代码就叫开闭原则的代码,比方说支付代码,一开始用的是支付宝的接口,后面我又加了一个微信支付接口,那么后面改的代码应该不会修改到原来的支付宝接口上(我知道很多人写这种接口的时候一般会用到一个type去表示是走支付宝还是走微信进来的数据,因为我那时候就是这样写的,那后面再进来其他的支付接口,那这个方法维护成本就很高了)

 

里式替换原则

里式替换原则的英文翻译是:Liskov Substitution Principle,缩写为 LSP。子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。

子类在设计的时候,要遵守父类的行为约定(或者叫协议)。父类定义了函数的行为约定,那子类可以改变函数的内部实现逻辑,但不能改变函数原有的行为约定。这里的行为约定包括:函数声明要实现的功能;对输入、输出、异常的约定;甚至包括注释中所罗列的任何特殊说明。实际上,定义中父类和子类之间的关系,也可以替换成接口和实现类之间的关系。

打个比方,我在父类里写的按某字段顺序排序的一个接口,我子类重写了他的接口,改成了按某字段倒叙排序的接口,那这个时候就是违背了里氏替换原则。

 

接口隔离原则

接口隔离原则的英文翻译是“ Interface Segregation Principle”,缩写为 ISP。Robert Martin 在 SOLID 原则中是这样定义它的:“Clients should not be forced to depend upon interfaces that they do not use。”直译成中文的话就是:客户端不应该被强迫依赖它不需要的接口。其中的“客户端”,可以理解为接口的调用者或者使用者。

  • 一组 API 接口集合

在设计微服务或者类库接口的时候,如果部分接口只被部分调用者使用,那我们就需要将这部分接口隔离出来,单独给对应的调用者使用,而不是强迫其他调用者也依赖这部分不会被用到的接口。

  • 单个 API 接口或函数

如果把“接口”理解为单个 API 接口或函数,部分调用者只需要函数中的部分功能,那我们就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数。

  • OOP 中的接口概念

如果把“接口”理解为 OOP 中的接口,也可以理解为面向对象编程语言中的接口语法。那接口的设计要尽量单一,不要让接口的实现类和调用者,依赖不需要的接口函数。

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

单一职责原则针对的是模块、类、接口的设计。接口隔离原则相对于单一职责原则,一方面更侧重于接口的设计,另一方面它的思考角度也是不同的。接口隔离原则提供了一种判断接口的职责是否单一的标准:通过调用者如何使用接口来间接地判定。如果调用者只使用部分接口或接口的部分功能,那接口的设计就不够职责单一。

 

依赖反转原则

  • 控制反转

框架提供了一个可扩展的代码骨架,用来组装对象、管理整个执行流程。程序员利用框架进行开发的时候,只需要往预留的扩展点上,添加跟自己业务相关的代码,就可以利用框架来驱动整个程序流程的执行。这里的“控制”指的是对程序执行流程的控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用框架之后,整个程序的执行流程可以通过框架来控制。流程的控制权从程序员“反转”到了框架。

  • 依赖注入

依赖注入和控制反转恰恰相反,它是一种具体的编码技巧。我们不通过 new 的方式在类内部创建依赖类的对象,而是将依赖的类对象在外部创建好之后,通过构造函数、函数参数等方式传递(或注入)给类来使用。

  • 依赖注入框架

我们通过依赖注入框架提供的扩展点,简单配置一下所有需要的类及其类与类之间依赖关系,就可以实现由框架来自动创建对象、管理对象的生命周期、依赖注入等原本需要程序员来做的事情。

  •  依赖反转原则

依赖反转原则也叫作依赖倒置原则。这条原则跟控制反转有点类似,主要用来指导框架层面的设计。高层模块不依赖低层模块,它们共同依赖同一个抽象。抽象不要依赖具体实现细节,具体实现细节依赖抽象。

 

KISS 原则和 YAGNI 原则

  • KISS 原则(Keep It Simple and Stupid)

就是保持代码可读和可维护的重要手段。代码足够简单,也就意味着很容易读懂,bug 比较难隐藏。即便出现 bug,修复起来也比较简单。

  • YAGNI 原则(You Ain’t Gonna Need It)

不要去设计当前用不到的功能;不要去编写当前用不到的代码。实际上,这条原则的核心思想就是:不要做过度设计。

 

DRY 原则(Don’t Repeat Yourself)

  • DRY 原则

实现逻辑重复、功能语义重复、代码执行重复。实现逻辑重复,但功能语义不重复的代码,并不违反 DRY 原则。实现逻辑不重复,但功能语义重复的代码,也算是违反 DRY 原则。除此之外,代码执行重复也算是违反 DRY 原则。

  • 代码复用性

提高代码可复用性的一些方法:

  1. 减少代码耦合
  2. 满足单一职责原则
  3. 模块化
  4. 业务与非业务逻辑分离
  5. 通用代码下沉
  6. 继承、多态、抽象、封装
  7. 应用模板等设计模式

 

迪米特法则(Law of Demeter)

  • 高内聚

高内聚,就是指相近的功能应该放到同一个类中,不相近的功能不要放到同一个类中。相近的功能往往会被同时修改,放到同一个类中,修改会比较集中,代码容易维护。

  • 松耦合

松耦合,在代码中,类与类之间的依赖关系简单清晰。即使两个类有依赖关系,一个类的代码改动不会或者很少导致依赖类的代码改动。

  • 如何理解“迪米特法则”

不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。迪米特法则是希望减少类之间的耦合,让类越独立越好。每个类都应该少了解系统的其他部分。一旦发生变化,需要了解这一变化的类就会比较少。

 

(最后几个记得有点简单了,后面补补)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值