【程序设计】程序设计的七大原则

        常言道理论是用来指导实践的,而理论又是通过实践不断检验和修正的结果,理论和实践就是这样相互促进,最后将一个领域推向新的高度。面向对象编程出现的半个多世纪里,设计原则就是在无数前辈的理论和实践中产生的。在我们日常开发中,会经常用到各种设计模式,设计原则就是这些设计模式的理论,而设计模式则是设计原则的实践。

       作为一名java程序员,我们都知道面向对象编程有三大特性,分别是封装、多态和继承。设计原则就是在这些特性的基础上进一步延伸和补充,让我们的代码更加健壮,具有较高的复用性和可扩展性,使得程序设计变成一门艺术。

1 单一职责

定义:不要存在多于一个导致类变更的原因

        单一职责顾名思义,就是一个框架、类、方法只负责一件事情,只能有一个能引起它变化原因。它的优势就是可以降低代码的复杂度,提高可读性和可维护性,使得同一模块的功能更加内聚。单一职责看来比较好理解,但实践起来可能会比较难,因为业务或者功能的拆分从来不是一件简单的事情,包括拆分的维度和粒度,这高度依赖于程序员的代码积累和业务素养。

2 开闭原则

定义:软件中的对象(类、模块、函数等)应该对于扩展是开放的,但是对于修改是关闭的。

        开闭原则是面向对象最重要的设计原则,简单理解就是,我们写的代码不能因为需求的变化而变化,应该通过扩展的方式来适应变化。提倡一个类一旦开发完成,后续增加新功能就不应该通过修改这个类来完成,而应该通过继承,增加新的类。如果对原有的类进行修改,那么涉及到这个类的所有功能都有出错的风险,需要投入额外的测试资源,增加了代码的维护成本。

        开闭原则除了体现在代码的扩展性强之外,另外的潜台词是:控制需求变动风险,降低维护成本,毕竟在企业中,更看重的是维护成本。当然原来的类不是一定不能修改,如果对原来的代码很熟悉,涉及场景比较少、风险可控的情况下是可以修改的,或者代码面临重构,开闭原则就可以暂时放弃。

3 依赖倒置原则

定义:高层模块不应该依赖低层模块,两者都应该依赖于抽象。

        依赖倒置的中心思想是面向接口编程,话外的意思是相对于细节的多变性,抽象的东西要稳定的多。核心就是要依赖于抽象,不应该依赖于具体的实现,在java中的具体表现形式有以下几种:

  1. 模块间的依赖通过抽象发生,实现类之间不直接发生依赖关系,其依赖关系是通过接口或抽象类产生的;
  2. 接口或抽象类不依赖于实现类;
  3. 实现类依赖接口或抽象类。

        依赖倒置原则可以降低类之间的耦合性,提高系统稳定性,降低并行开发引发的风险,同时能提高代码的可读性和可维护性。

4 接口隔离原则

定义:用多个专门的接口,而不是使用单一的总接口,客户端不应该依赖他不需要的接口。

        接口隔离原则强调的是一个类对另一个类的依赖应该建立在最小的接口上,我们针对每一类业务要建立单独的接口,接口中的方法尽量少,而不需要复杂臃肿的接口,这也符合单一职责。例如DAO的接口,通常针对单表的操作是放在一个DAO中。

        接口隔离原则能够充分体现高内聚低耦合的设计思想,使得单个接口的设计灵活简单。但这里要注意,接口的拆分粒度要适中,过分细化也会导致系统设计的复杂化。

5 迪米特法则

定义:一个类对于其他类应该知道的越少越好,也就是一个对象对于其他对象了解的越少越好,只和朋友通讯,不和陌生人说话。

        迪米特法则又叫最少知道原则,初衷也是在于降低类之间的耦合性。这里提到了朋友的概念,那类和类的朋友关系包含哪些呢?其实就是关联和依赖的关系。

        具体包含:成员变量(关联)、方法的入参(依赖)、返回值(依赖)、方法内部实例化的对象(依赖)等,对于方法内部调用其他方法的返回值是不能称为朋友的。

        对于被依赖的类来说,无论内部逻辑多么复杂,都应该封装在类的内部,对外提供 public 方法,不泄露任何信息。所以迪米特法则能够体现封装的特性,也能降低类之间的耦合性。

6 里氏替换原则

定义:派生类(子类)在程序中替换其基类(超类)对象。

        里氏替换原则可以说是继承复用的基石,我们看一下继承带来的优缺点:

优点:

  • 提高代码的复用性,子类可以拥有父类的特征和行为;
  • 提高代码的扩展性,子类可以形似父类,也可以保留自我特征。

缺点:

  • 侵入性高,只要继承就有了父类的特征和行为,使得子类在一定程度上被约束,灵活性降低;
  • 增加了父子类的耦合性,如果父类中的变量或方法修改,就可能对子类的某些使用场景造成比较大的危害,同理,如果子类对父类中的方法重写也可能会造成未知的风险。

        可以说,继承包含了这样一层含义:父类中已经实现的方法,实际上是在约定规范和契约,虽然并不强制要求子类遵守这些规范,但是如果子类对这些已经实现的方法进行修改,就会破坏整个继承体系。里氏替换原则的出现就很好的对继承进行了约束,具体可以体现在以下几点:

  1. 子类必须实现父类的抽象方法,但不能重写(覆盖)父类非抽象(已实现)的方法;
  2. 子类可以增加自己特有的属性和方法;
  3. 子类重载父类的方法,方法的前置条件(即方法的入参)要比父类方法的入参更加宽松(否则父类的方法不会被执行);
  4. 子类重载父类的方法,方法的后置条件(即方法的返回值)要比父类的返回值更加严格或者相同。

        针对后面两条不太好理解,可以参考如下博客: 设计模式之里氏替换原则 - lovebeauty - 博客园

        如果子类中确实要改变父类中已经实现的方法,那么建议断绝继承关系,改用关联或者依赖来实现,也就是下面将要说的合成复用原则。

7 合成复用原则

定义:尽量使用对象的组合/聚合,而不是继承关系达到软件复用的目的。

        合成复用原则又叫组合优于继承,通过里氏替换原则我们可以知道子类重写方法会破坏继承体系,引发风险,所以建议使用关联或者依赖关系实现。

        继承会破坏类之间的封装性,父类的内部细节暴露给子类,称之为白箱操作,而通过组合/聚合的方式,将已有对象纳入到新对象中,使得对象的功能可以被调用,这种行为称为黑箱操作。



最后简单总结一下对七大设计原则的理解:

  • 时刻考虑程序未来的“变化”,将变的东西独立出来,与稳定功能的代码分离;
  • 一切都是基于面向接口编程,而不是面向实现编程;
  • 实现模块之间的松耦合、模块内部的高内聚。

下一遍链接:【设计模式-1】图文并茂:单例模式仅需要这一遍就够了,展示单例的使用场景及7种代码实现

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

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

相关文章

SAP 资产管理后台配置之设定主数据字段

前阵子给财务创建了一个固定资产类型,但同事使用时发现字段跟平时不一样。 正常是有下面这些标签页的 然后我找到主数据屏幕格式的配置里发现 发现格式默认错了 应该是默认我司的自定义格式ZSAP 但是改成ZSAP还是不会生效 需要给这个资产分类重新分配一下字段标签页…

vue-springboot基于javaEE的二手手机交易平台的设计与实现

在此基础上,结合现有二手手机交易平台体系的特点,运用新技术,构建了以 SpringBoot为基础的二手手机交易平台信息化管理体系。首先,以需求为依据,根据需求分析结果进行了系统的设计,并将其划分为管理员、用户…

Vue+elementUI引入MessageUI展示问题

VueelementUI引入MessageUI展示问题 1.出现问题的界面 2.解决问题 import "element-plus/theme-chalk/el-message.css";

nginx加快图片访问速度

(一)设置压缩 开启gzip和设置压缩类型 测试下:curl -I -H "Accept-Encoding:gzip,deflate" "http://old.cc.cnm/images/201604/index_img/8529_G_1460346831951.jpg" (二)图片设置缓存 http层级: proxy_connect_time…

【年度总结 | 2023】稳步前进吧,少年

🤵‍♂️ 个人主页: AI_magician 📡主页地址: 作者简介:CSDN内容合伙人,全栈领域优质创作者。 👨‍💻景愿:旨在于能和更多的热爱计算机的伙伴一起成长!!&…

局部线性嵌入(LLE)的代码示例以及详细数学解释

文章目录 局部线性嵌入(LLE)的数学原理LLE中的重建权重计算示例 LLE降维映射的详细解释LLE降维映射的示例示例数据集降维映射 从LLE的特征值和特征向量到低维数据(低维嵌入)特征值和特征向量的计算选择特征向量以获得低维表示构建…

探索小红书笔记API:挖掘数据背后的故事

随着数字化时代的到来,数据已经成为企业和个人决策的重要依据。小红书作为一个流行的社交电商平台,积累了大量的用户数据和内容。通过探索小红书笔记API,我们可以深入挖掘这些数据背后的故事,从而更好地理解用户需求和市场趋势。 …

SpringBoot中定义Bean的几种方式

引言 在Spring Boot应用程序中,定义Bean是非常常见的操作,它是构建应用程序的基础。Spring Boot提供了多种方式来定义Bean,每种方式都有其适用的场景和优势。本文将介绍Spring Boot中定义Bean的几种常见方式,包括使用Component、…

SpringCloud 和 Linux 八股文第三期五问五答

SpringCloud 和 Linux 八股文第三期五问五答 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的! ⭐点赞⭐收藏⭐不迷路!⭐ 1)Linux常用命令 2)如何查看测试项目的日志 一…

VSCode使用Remote SSH远程连接Windows 7

结论 VSCode Server不能启动,无法建立连接。 原因 .vscode-server 目录中的 node.exe 无法运行。 原因是Node.js仅在Windows 8.1、Windows Server 2012 R2或更高版本上受支持。 由于vscode基于node.js v14,不支持Windows 7操作系统。 另&#xff…

关于苹果iOS 16:揭开伪装成飞机模式的隐形蜂窝接入漏洞的动态情报

一、基本内容 在日常生活中,网络威胁不断演变,给个人和组织带来了一系列重大挑战。网络犯罪分子使用的一种最常见的、最具破坏性的方法之一就是网络钓鱼。这种攻击方式通过电子邮件、短信或其他通讯渠道冒充可信实体,诱使个人泄露敏感信息&am…

Hive表加工为知识图谱实体关系表标准化流程

文章目录 1 对源数据静态文件的加工1.1 分隔符的处理情况1.2 无法通过分隔符以及包围符区分字段1.3 数据中存在回车换行符 2 CSV文件导入Hive的建表2.1 包围符作用和功能2.2 Hive的建表导入2.3 数据文件导入 3 对Hive表中数据的清洗3.1 数据质量检查3.2 标准导图表的构建3.3 随…

从0到1入门C++编程——01 C++基础知识

文章目录 一、工具安装二、新建项目三、设置字体、注释、行号四、C基础知识1.数据类型2.输入输出3.运算符4.选择、循环结构5.跳转语句6.数组7.函数8.指针9.结构体 一、工具安装 学习C使用到的工具是Visual Studio,Visual Studio 2010旗舰版下载链接:点此…

软件测试/测试开发丨Python 内置库 多线程threading

线程基本使用 单线程 def main():print("在扔一个苹果")if __name__ "__main__":main()多线程 Python提供了thread、threading等模块来进行线程的创建与管理,后者在线程管理能力上更进一步,因此我们通常使用threading模块。创建一…

Vue.js和Node.js的关系--类比Java系列

首先我们看一张图 这里我们类比了Java的jvm和JavaScript的node.js。 可以看到,node.js是基础,提供了基础的编译执行的能力。vue,js是实际上定义了一种他自己的代码格式,以加速开发。

告别HTTP,拥抱HTTPS!免费SSL证书领取指南

为什么选择HTTPS? HTTP和HTTPS之间的主要区别在于安全性。HTTP是一种不安全的协议,数据在传输过程中是明文的,容易受到中间人攻击。而HTTPS通过SSL(Secure Sockets Layer)或TLS(Transport Layer Security&…

计算机视觉:朗伯光度立体法(Lambertian Photometric Stereo)

计算机视觉:朗伯光度立体法(Lambertian Photometric Stereo) 光度立体法简介朗伯光度立体法算法原理朗伯光度立体法matlab程序示例Albedo图Normal图Re_rendered图 参考文献 光度立体法简介 光度立体法,即Photometric Stereo, 最早…

啊哈c语言——4.10(练习)

1&#xff0e;请尝试用for循环打印下面的图形。 #include <stdio.h> #include <stdlib.h> int main() {int a,b,c,d,e;for(a 1;a < 10;a){if(a < 5){b a * 2 - 1;c 5 - a;}else{b 9 - (a - 5) * 2;c a - 5;}for(d 0;d < c;d ){printf(" "…

【LeetCode每日一题】1154. 一年中的第几天(直接计算+调用库函数)

2023-12-31 文章目录 [1154. 一年中的第几天](https://leetcode.cn/problems/day-of-the-year/)方法一&#xff1a;直接计算思路&#xff1a; 方法二&#xff1a;调用库函数思路 1154. 一年中的第几天 方法一&#xff1a;直接计算 思路&#xff1a; 1.根据所给的字符串&#…

【机器学习】快速入门!关于 Pandas 库的简介和常用方法整理

Pandas Pandas 简介1. 数据加载和存储加载数据&#xff1a;存储数据&#xff1a; 2. 数据清洗3. 数据统计和汇总4. 数据选择和过滤5. 数据合并和连接6. 时间序列处理创建时间序列数据&#xff1a;索引和选择&#xff1a;时间序列分析&#xff1a;时间序列可视化&#xff1a; 7.…