二、设计模式中的七大设计原则总结 - 【内功心法】

本文介绍了面向对象设计的几个核心原则,如单一职责原则强调类的功能单一,开闭原则提倡扩展性而不修改,LSP里氏替换确保子类替换父类的兼容性,接口隔离原则倡导接口定制化,依赖倒置降低耦合。KISS、YAGNI和DRY原则提供简洁、避免过度设计和消除重复的实用指导。
摘要由CSDN通过智能技术生成

1. 单一职责原则

1.1 概述

   Single Responsibility Principle, 简称SRP,一个类或模块只负责完成一个功能。例如服务, 模块, 类, 接口或方法等都需要遵循SRP.

目标:保证代码的可扩展性,可复用性,可读性等。

1.2 哪些角度可判定是否满足单一职责

  • 类中的代码行数, 函数【行数不超过100行, 个数不超过10个】或属性【不超过10个】过多, 会影响代码的可读性,考虑进行拆分;
  • 依赖的类是否过多,不符合高内聚,低耦合思想,考虑进行拆分
  • 私有方法是否过多,可考虑将私有方法拆分到一个类中,提供public的权限来进行访问,提高代码的可复用性;
  • 类的名字不太好起,侧面说明类的职责过多,考虑拆分.

平衡性:但是类的粒度的大小,要考虑实际情况,太细或太粗都不适合。

2.开闭原则

2.1 概述

   Open Close Principle,简称OCP, 对扩展开放,对修改关闭。当新需求过来的时候,少量修改或不修改就可以完成需求的开发, 即在原有代码上新增类,方法,而不是修改类或方法,就认为符合开闭原则。

目标:提高可扩展性。

思考: 若要新增类或方法,就需要预留好扩展点,那么需要下意识的去抽象,扩展,封装。抽象是稳定点,实现是非稳定点,实现只需要新增,就认为OCP是不错的。

OCP设计初衷:代码修改不影响原有代码的运行逻辑, 没有破坏原有单元测试,就认为此次修改是合格。

2.2 实现开闭原则的一些好的手段

  • 多态
  • 基于接口而非实现编程
  • 依赖注入
  • 设计模式

3.LSP里氏替换原则

3.1 概述

   子类对象可以替换父类对象,并保证原来程序的逻辑和正确性不受影响。又称“Design By Contract”按照协议来设计,子类设计时要遵守父类的协议,协议包括:输入,输出,异常以及注释。协议不能违背,但具体的实现可以由子类来确定。以下规定要满足:

  • 继承必须确保超类所拥有的性质在子类中仍然成立
  • 子类可以扩展父类的功能,但不能改变父类原有的功能
  • 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
  • 子类中可以增加自己特有的方法
  • 当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松
  • 当子类的方法实现父类的方法时(重载/重写或实现抽象方法)的后置条件(即方法的输出/返回值)要比父类更严格或相等

3.2 违背LSP的示例

  • 子类违背父类声明的功能。例如getOrder()函数父类声明是按照订单时间排序,但子类实现时,按照订单金额进行排序;
  • 子类违背父类对输入,输出和异常的约定。例如: 父类要求出错时返回null,但子类却抛出了异常
  • 子类违背了父类注释中罗列的任何特殊说明。

3.3 与多态的区别

多态是一种语法,是一种代码实现的思路;里氏替换是一种原则,用来指导继承关系中子类要如何设计。
image.png

3.4 里氏替换存在的意义

  • 优化已有实现。按照代码是不断演进的规律,后面可能会有更好的实现,便于进行替换;
  • 优化抽象设计。当一个子类无法按照父类的协议进行实现时,是不是父类的协议规范的不够抽象和通用;
  • 保证父类设计的初衷,能被子类完全理解。

4.接口隔离原则

4.1 概述

   Interface Segregation Principle, 简称ISP。Robert Martin在书中定位为:客户端不应该依赖它不需要的接口。这里的接口主要分为以下三种类型:

  1. 提供给第三方使用的OpenApi接口: 不同的第三方可能依赖当前系统的功能是不同的,因此要单独为每个第三方提供定制化的接口,不要写一个大而全的接口,让所有的系统都可以访问到
  2. 单个函数:函数的功能设计要单一,不要将多个功能逻辑全部放到一个函数中,与单一职责类似。但单一职责针对的是模块, 类或函数的设计,接口隔离指的是函数的设计,从侧面来说,接口隔离原则可以用于判断函数职责是否单一
  3. OOP中的Interface接口:语法中的概念, 类似于Java中的Interface接口。

4.2 实现接口隔离原则的一些标准

  • 为各个类建立它们需要的专有接口
  • 接口的设计应遵循"最小接口原则";
  • 一个类对一个类的依赖应该是建立在最小的接口上
  • 建立单一接口,不要建立庞大臃肿的接口

5.依赖倒置或反转原则

5.1 概述

Dependency Inversion Principle,简称DIP。英文描述为:

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.

   高层模块不应该依赖于低层模块,两者都应该依赖于抽象。此外,抽象不应该依赖于实现细节,实现细节依赖于抽象。所谓的高层模块指的是调用者,低层模块指的是被调用者。这条准则主要用于指导框架的设计,以Tomcat为例:Tomcat依赖与Servlet规范,Web项目也依赖于Servler规范,并实现了细节,Servlet规范代表抽象。在Tomcat中部署Web项目时,Tomcat代表高层调用模块,Web项目代表低层模块,两者都依赖于Servlet抽象。

优点:减少类之间的耦合性,提高系统稳定性,提高代码的可读性。

5.2 依赖控制,依赖注入以及依赖反转之间的关系

依赖控制(IOC,Inversion of Controller):指的是将代码的执行流程控制权交由框架来控制,框架提供可扩展点,客户端使用扩展点进行代码的具体实现;是一种设计思想,用来指导框架层面的设计。

11.png

依赖注入(DI,Depandency Injection):是一种具体的编码技巧,不直接通过new的方式创建对象,而是在外部创建完成后,通过构造函数,函数参数等形式传递(注入)进来, 这样注入的对象可以灵活的替换,提高了代码的可扩展性。典型的依赖注入框架就是依据该思想进行设计的,框架提供扩展点,只需要简单配置一下类,以及类与类之间的关系,框架就可以帮助我们实现自动创建对象,管理对象的生命周期等。

6.KISS,YAGNI以及DRY原则

KISS,Keep it short and simple, 尽量保持简单

YAGNI,You ain’t gonna need it, 不要做过度设计

DRY, Don’t repeat yourself, 不要写重复的代码

6.1 KISS原则

   衡量某种实现方案是否符合KISS的指标:代码行数,实现复杂度,逻辑复杂度以及代码的可读性等。但一些复杂的算法,本身就很复杂,用复杂的方式解决,并不违背KISS原则,例如KMP字符串匹配算法,本质是如何做的问题。最佳实践

  • 不要使用偏僻的技术来实现代码,一方面不利于维护,另一方面可读性低;
  • 不要重复造轮子:bug多,尽量使用优秀开源的工具类来实现
  • 不要过度优化:不要使用一些奇技淫巧,例如过于底层的函数,位运算等

6.2 YAGNI原则

不要提前写好以后可能会用到的代码,但扩展性是必要的,可预留好扩展点,本质是要不要做的问题。

6.3 DRY原则

常见的三种典型代码重复情况:

  • 实现逻辑重复。判断username和password的逻辑是一样的,写了两个相同的函数,但这种并不违反DRY原则。考虑到未来username和password的判断逻辑是可能发生变化的,抽象成统一的函数,应对未来变化时,违反了开闭原则,同时抽象出来的函数也违反了单一职责原则,更加推荐的做法是:将函数进行细粒度拆分,抽出稳定的逻辑,将不稳定的逻辑暴露出去;
  • 功能语义重复。指的是不同的函数实现了相同的功能,明显了违背了DRY原则;
  • 代码执行重复相同的判断由于分散到不同的函数中,导致函数调用的过程中,出现重复执行的情况,违背了DRY原则,推荐将重复执行的逻辑提取出来,只执行一次。

7. 迪米特法则

   Law of Demeter,简称是LOD,又称最小知识原则【The Least Knowledge Principle】。核心思想:不该有直接依赖关系的类之间,不要有依赖;有依赖的类之间,尽量只依赖必要的接口。详细解释如下:

  • 不该有直接依赖关系的类之间,不要有依赖:Controller只与Service层连接,不直接调用dao层
  • 有依赖的类之间,尽量只依赖必要的接口: 服务A提供给公司内部第三方调用多个接口,服务B仅需要接口1和2, 服务C仅需要接口2和3, 此时接口1,2,3不应该放到同一个接口中,应该将接口拆分,保证服务B和C仅依赖它们需要的接口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桃花猿

客官,赏点打酒钱

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值