6大设计原则解读

java1234

共 3069字,需浏览 7分钟

 · 2021-06-13

点击上方蓝色字体,选择“标星公众号”

优质文章,第一时间送达

起因:团队依次分享讲到 SOLID,虽然能知道大概,但是要比较准确地说出各个设计原则还是有很大的困难。因此,有了这篇文章。

SRP(Single Responsibility Priciple)

There should never be more than one reason for a class to change

有且仅有一个原因引起类的改变

最典型的例子,就是我们会创建用户,除了设置用户的基本属性还包括对用户的增删查改。显然,用户的基本属性和增删查改应该分离开来。

单一职责只用于接口、类、同时也适用于方法。

好处

  1. 类的复杂度降低

  2. 可读性和可维护性提供

  3. 变更引起的风险降低。

难点:

用 “职责”或“变化原因”来衡量接口或类的设计是否有利,但是“职责”和“变化原因”不可度量,因项目而已,因理解方式而异。

建议:

接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。生搬硬套单一职责会引起类的剧增,而且给维护带来非常多的麻烦,过于细分的职责会增加系统的复杂度。本来一个类可以实现的行为硬要拆分成两个类,然后通过组合或聚合耦合在一起,人为制造复杂度。

里氏替换原则(Liskov Substitution Principle)

里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章《Data Abstraction and Hierarchy》里面提出来的,主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中的蕴涵的原理。2002年,软件工程大师Robert C. Martin,出版了一本《Agile Software Development Principles Patterns and Practices》,在文中他把里氏代换原则最终简化为一句话:“Subtypes must be substitutable for their base types”,也就是说,子类必须能够替换成它们的基类。

LSP 讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。

第一种定义

if for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T

类型为 S 的对象 o1,类型为 T 的对象 o2,类型为 T 的所有程序 P, 当 o2 用 o1 替换之后,程序 P 的行为没有发生改变,那么 S 是 T 的子类。

第二种定义

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it

所有用基类的指针或者引用的函数,必须可以透明地使用其子类。

通俗地讲,只要父类能出现的地方,就可以使用其子类。这其实是对子类继承父类时,对子类的一个约束。具体指

  1. 子类必须完全实现父类的方法,一个子类型不得具有比基类型有更多的限制

  2. 子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。

  3. 子类也能够在基类的基础上增加新的行为。

  4. 里氏代换原则是对开闭原则的补充,它讲的是基类和子类的关系。

依赖倒置原则(Dependence Inversion Principle)

Hign level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend on abstractions.

  1. 高层模块不应该依赖底层模块,两者都应该依赖抽象

  2. 抽象不应该依赖细节

  3. 细节应该依赖抽象

翻译之后变为

  1. 类与类之间通过抽象类或接口来关联。

  2. 接口或抽象类不依赖实现类

  3. 实现类依赖抽象类

什么是依赖:

  1. 构造函数依赖

  2. Setter 方法依赖

  3. 接口声明依赖

一句话:面向接口编程

接口隔离原则(Interface Segregation Principle)

定义一

Client should not be forced to depend upon interface that they don't use

客户端不应该强制依赖它不需要的接口

定义二

They dependency of one class to another one should depend on the smallest possible interface.

类间关系应该建立在最小接口上

这里要与单一职责区分开来,单一职责是从业务逻辑划分的角度,类应该功能单一。而接口隔离指的是接口的方法要少。这里难点是如何把握度。接口过于分散,维护难度增加,接口过于集中,扩展性受限。和微服务的服务划分面临的问题是一样的。解决办法就是领域驱动。

迪米特原则(Law of Demeter)

也称最少知识原则(LKP)。一个类应该对自己需要耦合或者调用的类知道得最少。

Only talk to your immediate friends.

开放封闭原则(Open Close Priciple)

Software entities like classes modules and functions should be open for extension but closed for modification

软件实体(类、模块、函数)对扩展开放、对修改封闭

一句话:通过扩展来适配新需求而不是修改。当然,不是说一点也不需要修改,而是将修改降到最小。

总结

核心:高内聚,低耦合

SRP :对单个类的设计提供指导。高内聚

IS:对接口的方法给出了限制,要尽量的少。高内聚

DIP:子类和父类的依赖关系。子类要依赖父类,父类不能依赖子类。低耦合

LSP:对子类继承父类给出了约束。子类必须完成实现父类的方法,这样父类可以在多个子类之间透明切换。低耦合

LoD:对应类间依赖的约束。低耦合

OCP: 从类的角度对高内聚和低耦合的诠释。



版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:

https://blog.csdn.net/wenxueliu/article/details/98472238









浏览 9
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报