Java设计模式之六大设计原则

为什么要学习设计模式?

要知道设计模式就是软件工程的方法经验的总结,也是可以认为是过去一段时间软件工程的一个最佳实践,要理解,不要死记硬背。掌握这些方法后,可以让你的程序获得以下好处:

  • 代码重用性(相同功能的代码,不用多次编写)
  • 可读性(编程规范性,便于其他程序员的阅读和理解)
  • 可扩展性(当需要增加新的功能时,非常的方便,称为可维护)
  • 可靠性(当我们增加新的功能后,对原来的功能没有影响)
  • 使程序呈现高内聚,低耦合的特性。

当然设计是有限度的,不能无限的考虑未来的变更情况,否则就会陷入设计的泥潭而无法自拔。方法是死的,人是活,用的时候一定灵活运用,才能发挥它的作用。设计模式中六大设计原则,这些原则可以认为是设计模式的灵昏。下面先对六大设计原则简单梳理一下,然后再详细分析每一个设计原则。

设计模式的六大原则

  1. 单一职责原则:一个类或一个接口只干一件事,要实现类的职责单一,这也可以延伸到对方法的理解上,主要目的是为了便于理解代码的业务含义,提高代码的可读性;
  2. 里氏替换原则:里氏替换原则的本质是描述父类与子类之间的继承规则,子类对象无论何时都能替换父类对象,子类可以扩展父类的功能,但不能改变父类原有的功能,主要目的是为了防止继承泛滥,增强程序的分健壮性;
  3. 依赖倒置原则:是指高层不应该依赖低层,要面向接口编程,主要目的是为了方便的对代码结果进行升级扩展;
  4. 接口隔离原则:即用多个专门的接口,而不是用单一的总接口,客户端不应该依赖它不需要的接口,主要目的是功能解耦,高聚合、低耦合;
  5. 迪米特法则:一个类对自己所依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部,只和朋友交流,不和陌生人说话,减少代码臃肿
  6. 开闭原则:对扩展是开放的,对修改是关闭的,主要目的是为了降低维护带来的新风险;

单一职责原则

单一职责:一个类或接口只负责一项职责

好处:

  1. 类的复杂性降低,实现什么职责、具备什么功能都有清晰明确的定义;
  2. 可读性提高:类之间的复杂性降低,可读性就提高了;
  3. 可维护性提高:可读性提高了,也就更便于维护;
  4. 变更引起的风险降低:类或接口具有单一的功能职责,变更的范围变小,受影响的范围也小,风险也就变低了;

单一职责是几个设计原则里最简单,最容易理解,也是最不好把握的,因为职责的划分是仁者见仁,智者见智的,如果职责划分的颗粒度较粗,那就不符合单一职责的原则,或者失去了单一职责原则的意义;如果职责划分的颗粒度较细,也不太好,会引起类或接口的剧增,有过度设计的嫌疑,给维护带来一定的麻烦;因此,在单一职责这个原则上,是需要把据一定的灵活性的,毕竟原则是死的,人是活的嘛。

里氏替换原则

里氏替换原则的目的是增加程序的健壮性,核心思想是所有引用基类的地方必须能够透明地使用子类的对象,具体则体现在四个方面:

  1. 子类必须完全的实现父类的方法;
  2. 子类也可以有自己的个性;
  3. 覆盖或实现父类的方法时,输入参数可以被放大;
  4. 覆盖或实现父类的方法时,返回值类型可以被缩小;

好处:

  1. 加强程序的健壮性
  2. 版本升级时可以做到很好的兼容性,增加子类,原有的子类还可以继续运行;

开闭原则

开闭原则:一个类、接口或方法,对扩展是开放的,对修改是关闭的,具体点就是用抽象来构建框架,用实现来扩展细节,即尽量通过扩展实体的行为来实现变化,而不是通过修改现已有代码来实现变化。相信很多同学对这点是深有体会的,就是在维护一段有很多人反复维护修改过的代码的时候,每一个来改的人改之前都要口士芬芳一番,然后无可奈何的接受现状。

我认为开闭原则是仅次于单一职责的最简单、最需要被实践的原则,虽然简单,但是好处可大大的不简单:

  1. 提高软件产品的稳定性:开闭原则要求保持原有代码不变,添加新代码来实现软件的变化,这样可以避免改坏线上功能的情况,避免老用户的流失。
  2. 不影响原有测试代码的运行:遵守开闭原则,软件的变化,不会影响到原有的测试代码,避免测试出错。
  3. 提高代码的可复用性:面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
  4. 提高软件的可维护性:开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。
  5. 使代码更具模块化,易于维护:开闭原则可以让代码中的各功能,以及新旧功能独立存在于不同的单元模块中,一旦某个功能出现问题,可以很快地锁定代码位置作出修改,由于模块间代码独立不相互调用,更改一个功能的代码也不会引起其他功能的崩溃。

依赖倒置原则

依赖倒置原则的核心是面向接口接口编程,主要体现在几个方面:

  1. 高层模块不应该依赖低层模块,两者都应该依赖抽象;
  2. 抽象不应该依赖细节,细节应该依赖抽象;
  3. 依赖关系通过抽象类或接口实现,实现类之间不直接发生依赖关系;
  4. 接口或抽象类不依赖于实现类,实现类依赖接口或抽象类;

好处:

  1. 降低类间的耦合性:依赖倒置原则可以降低类间的耦合性,使得代码更加健壮,更加耐久。
  2. 提高系统的稳定性:依赖倒置原则可以提高系统的稳定性,使得代码更加稳定可靠。
  3. 减少并行开发引起的风险:依赖倒置原则可以减少并行开发引起的风险,使得并行开发更加高效。
  4. 提高代码的可读性和可维护性:依赖倒置原则可以提高代码的可读性和可维护性,使得代码更加易于理解和维护。

接口隔离原则

接口隔离原则是指类或接口间的依赖应该建立在最小接口上,具体就是:

  1. 一个类对一个类的依赖应该建立在最小的接口之上;
  2. 要建立单一的接口,不要建立庞大臃肿的接口;
  3. 接口要尽量细化,接口中的方法要尽量的少,而不要建立一个庞大的接口供很多的依赖类来调用;

这里有的小伙们可能就有疑问了,这好像与单一职责有点类似呀!是的,确实有点类似,但是完全不同,单一职责强调的是类和接口的职责要单一,并没有强调接口的方法也要少,而接口隔离原则强调的是接口方法的松散程度;

  1. 降低耦合度:接口隔离原则将接口细化,减少了不相关的方法和依赖关系,降低了模块之间的耦合度。
  2. 提高灵活性:通过细粒度的接口定义,系统更容易适应变化,可以灵活地替换实现,而不影响其他部分的代码。
  3. 增强可维护性:接口隔离原则使得代码更加清晰、可读性更高,便于理解和维护。
  4. 提高代码复用性:通过接口的细化和适配器模式的使用,可以实现接口的复用,减少重复代码的编写。

迪米特原则

迪米特法则又叫 最少知道原则,即一个类对自己所依赖的类知道的越少越好。具体表现:

  1. 对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public 方法,不对外泄露任何细节信息。
  2. 两个实体间无需直接通信,可以通过第三方进行间接调用。
  3. 迪米特法则还有一个更简单的定义:只与直接的朋友通信。那什么是“直接朋友”呢?直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖、关联、组合、聚合等。我们称出现成员变量、方法参数、方法返回值中的类为直接朋友,而出现在局部变量中的类不是直接朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

好处:

  1. 降低类之间的耦合度:迪米特原则要求限制对象之间的直接交互,减少对象之间的依赖关系,避免出现复杂的交互关系和耦合度高的代码。
  2. 提高模块的相对独立性:通过迪米特原则,我们可以将对象之间的依赖关系转化为通过第三者间接交互,增加了系统的独立性和可维护性。
  3. 提高类的可复用率和系统的扩展性:由于迪米特原则降低了类之间的耦合度,使得类更加独立和可复用,同时也使得系统更加易于扩展和维护。

总结

最后,还是要强调一点,设计原则和设计模式绝对不是灵丹妙药,全用上就是好。当然设计原则有人理解是六种,也有理解是七种的。不管理解是几种,设计模式和设计原则属于方法论的内容,是要帮助我们解决具体的业务问题的,当然需要具体问题具体对待。

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

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

相关文章

膝关节检测之1设计目标手势与物体交互的动画

原来只用unity自带的IK,发现背部不能动,且手和手指的移动和旋转试了好像没法通过animation实现(加入关键帧并修改最终状态的数值后播放没有变化,确定最终关键帧的数值已经改了的)。看资料,发现final IK&…

thinkphp6入门(9)-- 获取url路径中的应用名、控制器名、操作名

如果使用了多应用模式,可以通过下面的方法来获取当前应用 app(http)->getName(); 获取当前控制器 Request::controller(); 获取当前操作 Request::action(); 在中间件middleware中是无法获取控制器和操作的 需要将middleware的引入修改为 config 目录下的 ro…

乐器经营商城小程序的作用是什么

乐器产品覆盖的人群非常广,小学生、老年人都有不小需求,也因此市场中的从业商家相对较多,产品丰富可供消费者选购,然而在实际经营中,线上线下面临痛点不少。 通过【雨科】平台搭建乐器小程序商城,将所有产品…

CCF CSP认证 历年题目自练Day31

题目一 试题编号: 202206-1 试题名称: 归一化处理 时间限制: 500ms 内存限制: 512.0MB 题目背景 在机器学习中,对数据进行归一化处理是一种常用的技术。 将数据从各种各样分布调整为平均值为 0、方差为 1的标准分布&a…

Stm32_标准库_9_TIM

频率(HZ)是频率的基本单位1HZ是1s的倒数 STM32F103C8T6一般情况给定时器的内部时钟都是72MHz(系统主频率) TIM基本构成 计数器、预分频器、自动化重装 // 都是16位其中计数器、自动化重装,都是16位换算成10进制范围为[0, 655536] 时间 1 /…

【全网最细】谷歌小恐龙无敌代码它来了!

谷歌小恐龙是什么? 每次断网的时候,大家是不是都会玩一会,小恐龙快跑的游戏,或者在信息课上玩一玩,对不对? 还没玩过的小伙伴也不用担心,打开谷歌,输入这段网址:chrome…

C++智能指针(三)——unique_ptr初探

与共享指针shared_ptr用于共享对象的目的不同,unique_ptr是用于独享对象。 文章目录 1. unqiue_ptr的目的2. 使用 unique_ptr2.1 初始化 unique_ptr2.2 访问数据2.3 作为类的成员2.4 处理数组 3. 转移所有权3.1 简单语法3.2 函数间转移所有权3.2.1 转移至函数体内3.…

软件工程与计算总结(十一)人机交互设计

目录 ​编辑 一.引例 二.目标 三.人类因素 1.精神模型 2.差异性 四.计算机因素 1.可视化设计 2.常见界面类型 五.人机交互设计的交互性 1.导航 2.反馈 3.设计原则 六.设计过程 1.基本过程 2.界面原型化 一.引例 无论软件功能多么出色,亦或内部的构造…

LENOVO联想笔记本小新 Pro-14 2021AMD处理器ACH版(82MS)原厂Win10系统

下载链接:https://pan.baidu.com/s/1-KZ8Y9NmkS7nDXcMbhZLHw?pwdyrkx 系统自带所有驱动、出厂主题壁纸、系统属性专属LOGO标志、Office办公软件、lenovo联想电脑管家等预装程序 所需要工具:16G或以上的U盘 文件格式:ISO 文件大小&#xff1…

深入篇【C++】总结智能指针的使用与应用意义(auto_ptr/unique_ptr/shared_ptr/weak_ptr)底层原理剖析+模拟实现

深入篇【C】总结智能指针的使用与应用意义&&(auto_ptr/unique_ptr/shared_ptr/weak_ptr)底层原理剖析模拟实现 智能指针的出现智能指针的使用应用意义/存在问题智能指针原理剖析模拟实现auto_ptrunique_ptrshared_ptrweak_ptr 智能指针的出现 首先我们要理…

vscode ssh linux C++ 程序调试

vscode调试c++程序相比vs2022要复杂很多,vs2022可以"一键运行调试",vscode则需要自己配置。 ​vscode调试程序时,会在当前工作目录产生.vscode 目录, 该目录有两个重要文件launch.json和tasks.json, 下面介绍两种调试方法: 手动调试和自动调试。 手动调试 不管…

VUE树结构实现

实现效果: 数据库表结构如下: 要求:需要有parentId,id。parentId就是父记录的id 表数据要求:一定不要让一条记录的parentid和id相同 前端代码: 注意:el-table标签里面需要加上属性,才可以有下拉箭头的样式 <el-table v-loading="listLoading" :data

Spring Boot中的异步编程:解决的问题与应用场景

Spring Boot中的异步编程&#xff1a;解决的问题与应用场景 在现代Web应用程序中&#xff0c;高并发和性能是至关重要的。为了处理大量的请求和任务&#xff0c;异步编程成为了不可或缺的一部分。Spring Boot提供了强大的异步编程支持&#xff0c;可以显著提高应用程序的吞吐量…

【Java 进阶篇】JavaScript Math对象详解

在JavaScript编程中&#xff0c;Math对象是一个非常有用的工具&#xff0c;用于执行各种数学运算。它提供了许多数学函数和常数&#xff0c;可以用于处理数字、执行几何运算、生成随机数等。在本篇博客中&#xff0c;我们将深入探讨JavaScript中Math对象的各种功能和用法。 什…

LiveMedia视频中间件视频隐私打码直播解决方案

一、方案背景 随着科技的发展&#xff0c;视频监控系统已经成为了我们生活中不可或缺的一部分。无论是在公共区域&#xff0c;还是在私人场所&#xff0c;我们都可以看到各种各样的监控设备。这些设备的出现&#xff0c;无疑提高了我们的生活安全&#xff0c;使得我们可以更好地…

Gin,Gorm实现Web计算器

目录 仓库链接0.PSP表格1. 成品展示1.基础运算2. 清零回退3.错误提示4.历史记录拓展功能1.前端可修改的利率计算器2.科学计算器3. 按钮切换不同计算器模式4.用户在一次运算后不清零继续输入操作符&#xff0c;替换表达式为上次答案 2.设计实现过程3.代码说明4.心路历程和收获 仓…

企业级CI/CD 持续集成/交付/发布

jenkins 安装与使用 nmcli g hostname jenkins 加载缓存 yum makecache fast 上传jdk11、jdk8 获取、上传war包 1、jenkins.io/download 2.4.27 2、老师发的 上传 maven 上传tomcat软件包 &#xff08;apache.org-tomcat8-下载&#xff09; 注意8009端口 /usr... vi /etc/pro…

react中ant.design框架配置动态路由

目录 什么是动态路由&#xff1f; 应用场景&#xff1a; ant.design动态路由如何配置&#xff1a; 首先&#xff1a;找到app.tsx文件 然后&#xff1a;找到menuHeaderRender 其次&#xff1a;修改menuHeaderRender为menuDataRender​编辑 最后&#xff1a;在箭头函数里re…

linux内存、cpu、进程、端口、硬盘管理

这里讲解一下linux内存、cpu、进程、端口、硬盘管理命令操作,更多linux常用命令见:一些经常使用的linux命令 一、内存、cup 管理 top 命令 1、top 命令的第一行 top - 10:11:23 up 12:10, 2 users, load average: 0.00, 0.02, 0.05 依次对应&#xff1a; 系统当前时间 10:11:…

Vite与Webpack谁更胜一筹,谁将引领下一代前端工具的发展

你知道Vite和Webpack吗&#xff1f;也许有不少“程序猿”对它们十分熟悉。 Webpack Webpack是一个JavaScript应用程序的静态模块打包工具&#xff0c;它会对整个应用程序进行依赖关系图构建。而这也会导致一个不可避免的情况&#xff0c;使用Webpack启动应用程序的服务器&…