三、1如何运用设计原则之SOLID原则写出高质量代码?

news2024/12/28 5:29:28

你好我是程序员雪球。接下来我们学习一些经典的设计原则。其中包括SOLID,KISS,YAGNI,DRY,LOD等。其实这些设计原则从字面意思理解并不难。但是“看懂”和“会用”是两回事,而“用好”就难上加难了。

先来了解SOLID原则,他是由5个原则的首字母组成,分别是单一职责原则,开闭原则,里氏替换原则,接口隔离原则和依赖反转原则。

9384507cb62f467b9647c5a13b9d6984.png

 

单一职责原则(SRP)
指的是一个类或者一个模块只负责完成一个职责(或功能)。也就是说不要设计大而全的类,要设计粒度小,功能单一的类。单一职责原则是为了实现代码高内聚,低耦合,提高代码的复用性,可读性,可维护性。但是拆得过细,反倒会降低内聚性,影响可维护性 。

如何判断类的职责是否单一?
如果类的设计出现下面的情况,这可以判断不符合单一职责:
1、类中代码行数,函数和属性过多;
2、类依赖的其他类过多,或者依赖类的其他类过多;
3、私有方法过多;
4、比较难给类起一个命名;
5、类中的大量方法都是集中操作类中的某几个属性;

开闭原则(OCP)
开闭原则指的是软件实体(模块,类,方法等)应该“对扩展开发,对修改关闭”。也就是添加一个新的功能时,应该在已有的代码基础是扩展新的模块,类,方法等,而不是修改已有代码(模块,类,方法等),所以说代码的扩展性是重点。

提高代码的扩展性有哪些方法?
多态,依赖注入,基于接口而非实现编程,以及大部分的设计模式(装饰,策略,模板,职责链,状态等)。

如何在项目中灵活应用开闭原则?
对于比较确定,短期内可能会扩展,或者需求改动对代码影响较大的情况,或者实现成本不高的扩展点,在编码代码的时候,可以事先做些扩展设计。对未来不确定,或者实现起来比较复杂的扩展点,你可以等有需求驱动的时候,再通过代码重构的方式来支持扩展的需求。代码的扩展性有时会跟可读性相冲突,你需要做好权衡。

里氏替换原则(LSP)
指的是子类对象能够替换程序中父类对象出现的任何地方,并且保证原来程序的逻辑行为不变及正确性不被破坏。其核心思想“按照约定来设计”,这里的约定包括:函数生命要实现的功能;对输入,输出,异常的约定;甚至包括注释中所罗列的任何特殊说明。

接口隔离原则(ISP)
指的是:客户端不应该被迫依赖它不需要的接口,其中的“客户端”可以理解为接口的调用者或者使用者。“接口”可以理解为下面三种场景:一组API接口集合,单个API接口或函数,OOP中的接口概念。接下来我们一起来解读这三种场景。

一组API接口集合
可以是某个微服务的接口,也可以说某个类库的接口。如果部分接口被部分调用者使用,你可以将这部分接口隔离出来,单独给这部分调用者使用。比如app前后端分离的接口实现中,我们应该将后台管理和APP前台的接口分开定义,应该像删除这里功能一般只有后台管理才有权限,这样可以做到隔离保护,避免前台用户误删用户信息。

单个API接口或函数
部分调用者只需要函数中的部分功能,那你可以将函数拆分成粒度更细的对个函数,让调用者只依赖它需要的那个细粒度函数。函数的设计功能要单一,不要将多个不同的功能逻辑在一个函数实现,这样可以提高代码的可读性和可维护性。

OOP的接口概念。
指的是面向对象编程语言的接口语法,接口设计要单一,不要让接口的实现类也调用者,依赖不需要的接口函数。比如JAVA中的interface,假如你在项目中用了三个外部系统:Redis,MySQL,Kafka。每个系统都对应一系列配置信息,比如地址,端口,访问超时等。为了在内存中存储这些配置信息,供项目中的其他模块来使用,我们分别设计实现了三个Configuretion类:RedisConfig,MysqlConfig,KafkaConfig。这样更加灵活,易扩展,易复用。

接口隔离原则和单一职责原则的区别
单一职责原则是针对模块,类和接口设计。接口隔离原则侧重于接口的设计,它是提供了一种判断接口的职责是否单的标准,即调用者只使用部分接口或者接口功能,那接口的设计就不够单一。

依赖反转原则(DIP)
我们先来了解三个概念:控制反转(IOC),依赖注入(DI),依赖注入框架(DIF)。

控制反转(IOC)
“控制”指的是程序执行流程的控制,而“反转”指的是在没有使用框架之前,程序员自己控制整个程序的执行。在使用了框架之后,整个程序的执行流程通过框架来控制。流程的控制权从程序员“反转”到了框架。控制反转是一种比较笼统的设计思想,一般用来指导框架层面的设计,比如模板设计模式,依赖注入方式等。

依赖注入(DI)
是一种编程技巧,不通过new()的方式在类内部创建依赖类对象,而是将依赖的类对象在外部创建好之后,通过构造函数,构造参数等方式传递(或注入)给类使用,这样提高了代码的扩展性。

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

依赖反转原则(DIP)
高层模块不依赖底层模块,高层模块和底层模块应该通过抽象来相互依赖。除此之外,抽象不依赖具体的细节,具体实现细节依赖抽象。我们拿Tomcat这个Servlet容器为例子:
tomcat是运行java web应用程序的容器。那么tomcat是高层模块,web应用就是底层模块。tomcat与web应用代码直接没有直接的依赖关系,两者都依赖同一个“抽象”,也就是Servlet规范。servlet规格不依赖具体的tomcat容器和web应用的实现细节,而tomcat容器和web应用依赖servlet规范。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/713398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EMC学习笔记(十三)背板的EMC设计

背板的EMC设计 1.背板槽位的排列1.1 单板信号的互联要求1.2 单板板位结构1.2.1 板位结构影响1.2.2 板间互联电平、驱动器件的选择 2.背板的EMC设计2.1 接插件的信号排布与EMC设计2.1.1 接插件的选型2.1.2 接插件模型与针信号排布 2.2 阻抗匹配2.3 电源、地分配 1.背板槽位的排列…

深度学习的技术原理

目录 人工智能 深度学习的应用场景 神经网络 卷积神经网络(CNN) 一个神经网络运行的可视化展示 人工智能 信息技术是人类历史上的第三次工业革命, 计算机、 互联网、智能家居等技术的普及极大地方便了人们的日常生活。 通过编程的方式&…

xshell安装jdk1.8环境

xshell安装jdk1.8环境 大家好,今天我们来学习一下xshell安装jdk1.8环境,好好看,好好学,超详细的 第一步 进入xshell官网下载 第二步 打开xshell新建一个会话,如下图: 第三步 输入你的名称、主机ip、端口号(…

Nginx负载均衡与动静分离

一、Nginx负载均衡: 1.概述: Nginx是一款http服务器软件,支持高达50000个并发连接数的响应。 (1)拥有强大的处理静态资源的能力。 (2)运行稳定。 (3)CPU&#xff0c…

nginx+tomcat负载均衡和动静分离

目录 1.部署nginx 2.部署两台tomcat 3.配置nginx 1.部署nginx vim /vim/lib/systemd/system/nginx.service 2.部署两台tomcat 进入第一台装第一个tomcat vim /etc/profile vim /usr/local/tomcat/webapps/test/index.jsp 重启 进入第二台安装第二台tomcat vim /usr/local/tom…

【电路原理学习笔记】第2章:电压、电流和电阻:2.1 原子结构

第2章:电压、电流和电阻 2.1 原子结构 元素:不能用化学方法分解成更简单形式的物质称为元素。原子:原子是体现元素特性的最小粒子。原子核:原子核由质子和中子组成,质子带有正电荷,中子呈中性。电子带有负…

原型模式的学习与使用

1、原型模式的学习 当我们需要创建一个对象,并且该对象的创建过程比较复杂或者耗时时,可以使用原型模式。原型模式通过复制现有对象的属性来创建新的对象,而不是从头开始创建。   在原型模式中,我们定义一个原型接口或抽象类&am…

CMU 15-445 -- Buffer Pool - 03

CMU 15-445 -- Buffer Pool - 03 引言Buffer PoolsBuffer Pool ManagerLock 和 Latch 的区别PAGE TABLE 和 PAGE DIRECTORYMultiple Buffer PoolsPrefetchingScan SharingBuffer Pool BypassOS Page Cache Buffer Replacement PoliciesLRUClockLRU 与 Clock 的问题LRU-KLocaliz…

如何优雅的将 Docker 镜像从 1.43G 瘦身到 22.4MB

Docker 镜像的大小对于系统的 CI/CD 等都有影响,尤其是云部署场景。我们在生产实践中都会做瘦身的操作,尽最大的可能使用 Size 小的镜像完成功能。下文是一个简单的 ReactJS 程序上线的瘦身体验,希望可以帮助大家找到镜像瘦身的方向和灵感。 …

Helm之深入浅出Kubernetes包管理工具使用

Chart 使用 作者:行癫(盗版必究) 一:Chart 模板使用 1.创建chart ​ templates目录包括了模板文件;当Helm评估chart时,会通过模板渲染引擎将所有文件发送到templates目录中;然后收集模板的结果并发送给Kubernetes ​ values.yaml 文件也导入到了模板;这个文件包含了c…

北京大学2016计算机学科夏令营上机考试

目录 A:分段函数【水题】 B:单词翻转【暴力不水】 C:反反复复【字符串】 D:文件结构“图”【图】 E:Exchange Rates【这不是我能做的】 F:Dungeon Master【没看懂题目什么意思】 G:重建二叉树【树】 A:分段函数【水题】 #include<iostream> using namespace std;…

如何自学入门网络安全/黑客?【建议收藏】

建议一&#xff1a;黑客七个等级 黑客&#xff0c;对很多人来说充满诱惑力。很多人可以发现这门领域如同任何一门领域&#xff0c;越深入越敬畏&#xff0c;知识如海洋&#xff0c;黑客也存在一些等级&#xff0c;参考知道创宇 CEO ic&#xff08;世界顶级黑客团队 0x557 成员…

零基础学会Python编程——不同的运算:算术、关系与逻辑(1)

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 学习目标 一. 运算 1.算术运算 2.加法运算 3.减法运算 4.乘法运算 5.除法…

Redis从入门到精通【进阶篇】之消息传递发布订阅模式详解

文章目录 0. 前言1. 基本原理1.1 基于频道(Channel)的发布/订阅1.2 基于模式(Pattern)的发布/订阅 2. Redis 发布订阅实际应用2.1 Redis Sentinel2.1 SpringBoot Redis发布/订阅 3. Redis从入门到精通系列文章 0. 前言 发布订阅模式&#xff08;Publish-Subscribe Pattern&…

小而强大:通过容器化应用实现前端微服务

微服务架构是一种软件架构模式&#xff0c;用于构建复杂应用程序。它将一个大型的单体应用程序拆分为一组更小、更独立的服务&#xff0c;每个服务都运行在自己的进程中&#xff0c;并通过轻量级的通信机制进行交互。每个服务都专注于解决特定的业务功能或服务&#xff0c;并且…

Distractor-aware Siamese Networks for Visual Object Tracking(DaSiamRPN)

Distractor-aware Siamese Networks for Visual Object Tracking&#xff08;DaSiamRPN&#xff0c;ECCV2018&#xff09; 该论文针对以下三个问题&#xff0c;分别进行了改进&#xff1a; 常见的Siam类跟踪方法只能区分目标和无语义信息的背景&#xff08;即简单背景&#x…

MacBook(M1)上安装Ubuntu虚拟机

Mac&#xff08;M1&#xff09;上安装Ubuntu虚拟机 0.下载资料汇总 VMware Fusionhttps://www.vmware.com/products/fusion/fusion-evaluation.htmlubuntu-desktop-arm64.isohttps://cdimage.ubuntu.com/jammy/daily-live/current/ 1.安装VMware Mac版本的VMware叫 VMware …

SiamRPN++: Evolution of Siamese Visual Tracking with Very Deep Networks

SiamRPN: Evolution of Siamese Visual Tracking with Very Deep Networks&#xff08;CVPR2019&#xff09; 为什么2018年提出的SiamRPN网络还在用老式的AlexNet作为Siamese Network的特征提取网络呢&#xff1f;其实SiamRPN也尝试过用ResNet替代AlexNet&#xff0c;但发现效…

gitlab使用教程

一&#xff1a;账号管理 1、管理员添加 gitlab的用户分为管理员用户和普通用户&#xff0c;在界面上管理员会多了如下图所示的管理员区域&#xff0c;管理员拥有用户管理的功能&#xff0c;普通用户没有此功能。 通过管理员区域的用户-添加用户&#xff0c;根据提示填写必要…