当前位置: 首页 > news >正文

【设计模式】(二)设计模式六大设计原则

一、 设计原则概述

设计模式中主要有六大设计原则,简称为SOLID ,是由于各个原则的首字母简称合并的来(两个L算一个,solid 稳定的),六大设计原则分别如下:

1、单一职责原则(Single Responsibitity Principle)

2、开放封闭原则(Open Close Principle)

3、里氏替换原则(Liskov Substitution Principle)

4、接口分离原则(Interface Segregation Principle)

5、依赖倒置原则(Dependence Inversion Principle)

6、迪米特法则(Law Of Demter)

软件开发中我们要基于这六个原则,设计建立稳定、灵活、健壮的程序。

二、设计原则分

2.1 单一职责

单一职责原则的定义描述非常简单,也不难理解。一个类只负责完成一个职责或者功能。

也就是说在类的设计中 我们不要设计大而全的类,而是要设计粒度小、功能单一的类.

比如 我们设计一个类里面既包含了用户的一些操作,又包含了支付的一些操作,那这个类的职责就不够单一,应该将该类进行拆分,拆分成多个功能更加单一的,粒度更细的类.

2.2 开闭原则

定义:对扩展开放,对修改关闭

对扩展开放和对修改关闭表示当一个类或一个方法有新需求或者需求发生改变时应该采用扩展的方式而不应该采用修改原有逻辑的方式来实现。因为扩展了新的逻辑如果有问题只会影响新的业务,不会影响老业务;而如果采用修改的方式,很有可能就会影响到老业务受影响。

开闭原则是所有设计模式的最核心目标,也是最难实现的目标,但是所有的软件设计模式都应该以开闭原则当作标准,才能使软件更加的稳定和健壮。

优点:

  1. 新老逻辑解耦,需求发生改变不会影响老业务的逻辑

  2. 改动成本最小,只需要追加新逻辑,不需要改的老逻辑

  3. 提供代码的稳定性和可扩展性

2.3 里氏替换原则

如何理解里氏替换原则?

要理解里氏替换原则,其实就是要理解两个问题:

  • 什么是替换?
  • 什么是与期望行为一致的替换(Robert Martin所说的“必须能够替换”)?

1 ) 什么是替换 ?

替换的前提是面向对象语言所支持的多态特性,同一个行为具有多个不同表现形式或形态的能力。

以JDK的集合框架为例,List接口的定义为有序集合,List接口有多个派生类,比如大家耳熟能详的ArrayList, LinkedList。那当某个方法参数或变量是List接口类型时,既可以是ArrayList的实现, 也可以是LinkedList的实现,这就是替换。

2 ) 什么是与期望行为一致的替换?

在不了解派生类的情况下,仅通过接口或基类的方法,即可清楚的知道方法的行为,而不管哪种派生类的实现,都与接口或基类方法的期望行为一致。

不需要关心是哪个类对接口进行了实现,因为不管底层如何实现,最终的结果都会符合接口中关于方法的描述(也就是与接口中方法的期望行为一致).

或者说接口或基类的方法是一种契约,使用方按照这个契约来使用,派生类也按照这个契约来实现。这就是与期望行为一致的替换。

2.4 接口隔离原则

要为各个类建立它们需要的专用接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。

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

接口隔离原则和单一职责都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但两者是不同的:

  • 单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离。
  • 单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建。

2.5 依赖倒置原则

依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。

  1. 高层级的模块应该依赖的是低层级的模块的行为的抽象,取决于具体编程语言,可以是抽象类或者接口等技术;
  2. 第2句话其实很简单,只有一个意思:只要依赖了实现,就是耦合了代码,所以我们需要始终依赖的是抽象,而不是实现。
  • 传统的自定向下的设计

    传统设计方式采用自顶向下的原则, 逐级依赖,中层模块和高层模块的耦合度很高,如果需要修改其中的一个模块,则可能会导致其它很多模块也需要修改,牵一发动全身,不易于维护。

    不使用依赖反转的系统构架,控制流和依赖关系流的依赖箭头是一个方向的,由高层指向底层,也就是高层依赖底层

在这里插入图片描述

  • 依赖倒置原则

    依赖倒置原则的好处:

    • 减少类间的耦合性,提高系统的稳定性 . (根据类与类之间的耦合度从弱到强排列:依赖关系、关联关系、聚合关系、组合关系、泛化关系和实现关系 )
    • 降低并行开发引起的风险 (两个类之间有依赖关系,只要制定出两者之间的接口(或抽象类)就可以独立开发了)
    • 提高代码的可读性和可维护性

在这里插入图片描述

2.6 迪米特法则

大部分设计原则和思想都非常抽象,有各种各样的解读,要想灵活地应用到 实际的开发中,需要有实战经验的积累。迪米特法则也不例外。

简单来说迪米特法则想要表达的思想就是: 不该有直接依赖关系的类之间,不要有依赖;有依赖关系的类之间,尽量只依赖必要的接口。

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

相关文章:

  • LeetCode 热题 100 | 图论(二)
  • 【粉丝福利】一本书讲透ChatGPT,实现从理论到实践的跨越!大模型技术工程师必读
  • 线性代数笔记11--矩阵空间、秩1矩阵
  • 数据库-第四/五章 数据库安全性和完整性【期末复习|考研复习】
  • [Vulnhub]靶场 Web Machine(N7)
  • 【CSP试题回顾】202209-2-何以包邮?
  • 各中间件性能、优缺点对比
  • Android使用OpenGL和FreeType绘制文字
  • 【MATLAB】语音信号识别与处理:卷积滑动平均滤波算法去噪及谱相减算法呈现频谱
  • 第七篇:人工智能与机器学习技术VS量测(Measurement)- 我为什么要翻译介绍美国人工智能科技巨头IAB公司 - 它是如何赋能数字化营销生态的?
  • 前端工具网站合集(持续更新)
  • 数学建模介绍
  • 探索云原生世界:Serverless 技术的崛起与应用
  • Centos 9 安装 k8s
  • python基础使用之“__name__==‘__main__‘”作用
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • Android组件 - 收藏集 - 掘金
  • django开发-定时任务的使用
  • echarts花样作死的坑
  • emacs初体验
  • markdown编辑器简评
  • Node + FFmpeg 实现Canvas动画导出视频
  • React16时代,该用什么姿势写 React ?
  • RxJS: 简单入门
  • Twitter赢在开放,三年创造奇迹
  • 京东美团研发面经
  • 前端路由实现-history
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 如何进阶一名有竞争力的程序员?
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • ​水经微图Web1.5.0版即将上线
  • # Panda3d 碰撞检测系统介绍
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #控制台大学课堂点名问题_课堂随机点名
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • (11)工业界推荐系统-小红书推荐场景及内部实践【粗排三塔模型】
  • (3)llvm ir转换过程
  • (C语言)逆序输出字符串
  • (多级缓存)缓存同步
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)C#调用WebService 基础
  • (转)iOS字体
  • .Net CF下精确的计时器
  • .net FrameWork简介,数组,枚举
  • .Net 中Partitioner static与dynamic的性能对比
  • @transactional 方法执行完再commit_当@Transactional遇到@CacheEvict,你的代码是不是有bug!...
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [20161101]rman备份与数据文件变化7.txt
  • [2019.3.5]BZOJ1934 [Shoi2007]Vote 善意的投票
  • [AIGC] MySQL存储引擎详解
  • [CLickhouse] 学习小计
  • [Enterprise Library]调用Enterprise Library时出现的错误事件之关闭办法
  • [hihocoder1395] 最大权闭合子图
  • [JDBC-1] JDBC Base Template