系列文章目录


文章目录

  • 系列文章目录
  • 一、单一职责原则
    • 方块游戏的设计
  • 二、开放-封闭原则
    • 原则介绍
    • 何时应对变化
  • 三、依赖倒转原则
    • 依赖倒转原则介绍
    • 里氏代换原则
  • 总结


在这里插入图片描述

一、单一职责原则

单一职责原则,听字面意思,就是说功能要单一,他的准确解释是,就一个类而言,应该仅有一个引起他变化的原因,我们在做编程的时候,很自然的就会给一个类加各种各样的功能,比如我们写一个窗体应用程序,一般都会生成一个Formal这样的类,于是我们就把各种各样的代码,像某种商业运算的算法,或者数据库访问的SQL语句什么的都写进到这样的类中,这就意味着,无论任何需求要来,你都需要修改这个窗体类,这其实是很糟糕的,维护麻烦,复用不可能,也缺乏灵活性。

单一职责原则:就一个类而言,应该仅有一个引起他变化的原因。

方块游戏的设计

我们这里通过手机里的俄罗斯方块这款游戏为例,开发这个小游戏,我们应该怎么做呢?
我们可以先建立一个窗体,然后加一个用于游戏框的控件,一个按钮Button来控制‘开始’,最后计时器控制用于分时动画的编程,写代码当然就是编写计时器时间来绘出和删除方块,并做出堆积和消层的判断,再编写控件的键盘事件,如左箭头左移,右箭头右移等。这里我们思考,如果把所有的代码都写在了窗体这个java类里面,其实这样是不合理的,因为如果这样的话,如果要开发其他版本的俄罗斯方块,或者是Web版或者Windows窗台版的俄罗斯方块,那现在这个代码其实是不好复用的!
但这当中,有些东西是始终没变的,比如说下落、旋转、碰撞判断、移动堆积这些游戏逻辑。这些都是和游戏有关的逻辑,和界面如何表示没有什么关系,为什么要写在一个类里面呢?如果一个类承担的责任过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成的其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。 所以,我们应该找出那些是界面,那些是游戏逻辑,然后进行分离。

软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离。 其实要去判断是否应该分离出来类,也不难,那就是如果你能够想到多余一个的动机去改变一个类,那么这个类就具有多于一个的职责

二、开放-封闭原则

原则介绍

开放-封闭原则,是说软件实体(类、模块、函数等)应该可以扩展,但是不可修改

这个原则其实是有两个特征,一个是说‘对于扩展是开放的’ , 另一个是说‘对于修改是封闭的’ 。

我们在做任何系统的时候都不要指望系统一开始时需求绑定,就再也不会变化,这是不现实也不科学的想法,需求是一直变化的,那么如何在面对需求的变化时,设计的软件可以相对容易修改,不至于说,新需求依赖,就要把整个程序推倒重来。怎样的设计才能面对需求的改变却可以保持相对稳定,从而使得系统可以在第一个版本以后不断推出新的版本呢? 开放-封闭给了我们答案。设计软件要容易维护又不容易出问题的最好的办法就是多扩展,少修改。

何时应对变化

开放–封闭原则的意思就是说,你设计的时候,时刻要考虑,尽量让这个类足够好,写好了就不要去修改了,如果新需求来,我们增加一些类就完事了,原有的代码能不动则不动,但是,绝对的对修改关闭是不可能的,无论模块是多么的‘封闭’,都会存在一些无法对之封闭的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应对出哪种变化封闭做出选择。他必须先猜测出最有可能发生的变化种类,然后构造抽象来隔离那些变化。

但是,事先猜测是很难做到的,但我们却可以在发生小变化时,就及早去想办法,应对发生更大变化的可能,也就是说,等到变化发生时立即采取行动,在我们最初编写代码时,假设变化不会发生,当变化发生时,我们就创建抽象来隔离以后发生的同类变化

我们在简单工厂模式中,一开始只有一个加法程序,后面我们需要增加一个减法功能,我们发现,增加功能需要修改原来这个类,这就违背了今天所讲到的‘开放-封闭’ 原则,于是你就该考虑重构程序,增加一个抽象的运算类,通过一些面向对象的手段,如继承、多态等来隔离具体加法、减法与client耦合,需求依然可以满足,还能应对变化,这时我们再加乘除法功能,就不需要再去更改client类了二十增加乘法和除法的字类就可,即面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码,这就是开放–封闭原则 的精神所在。

当然,并不是什么时候应对变化都是容易的,我们希望的是在开发工作展开不久就知道可能发生的变化,查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。

开放封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。

三、依赖倒转原则

依赖倒转原则介绍

依赖倒转原则,原话解释是抽象不应该依赖细节,细节应该依赖于抽象,说简单点,就是要针对接口编程,不要对实现编程

依赖倒转原则
(1)高层模块不应该依赖低层模块。两个都应该依赖抽象。
(2)抽象不应该依赖细节。细节应该依赖抽象。

那么为什么要叫倒转呢?

在面向过程开发时,为了使得常用代码可以复用,一般都会把这些常用代码写成许许多多函数的程序库,这样我们在做新项目时,去调用这些低层的函数就可以了。比如我们做的项目大多要访问数据库,所以我们就把访问数据库的代码写成了函数,每次做新项目时就去调用这些函数。这也就叫做高层模块依赖低层模块。

其实问题也就出在这里,我们做新项目时,返现业务逻辑的高层模块都是一样的,但客户却希望使用不同的数据库或者储存信息方式,这时就出现麻烦了。我们希望能再次利用这些高层模块,但高层模块都是与低层的访问数据库绑定在一起的,没办法复用这些高层模块。这里我们以电脑举例,电脑里如果CPU、内存、硬盘都需要依赖具体的主板,主板一坏,所有的部件就都没用了,这显然不合理,反过来,如果内存坏了,也不应该造成其他部件不能用才对。而如果不管高层模块还是低层模块,他们都依赖于抽象,具体一点就是接口和抽象类,只要接口是稳定的,那么任何一个更改都不用担心其他受到影响,这就使得无论高层模块还是底层模块都可以很容易地被复用。

如果这里还不是很理解,也是很正常的,因为还有一个设计原则,让我们产生困惑。这个原则就叫里氏代换原则

里氏代换原则

里氏代换原则: 一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化

里氏代换原则: 子类型必须能够替换掉它们的父类型。

这里貌似是继承需要理解的概念,子类继承了父类,所以子类可以以父类的身份出现。
小问题:如果在面向对象设计时,一个是鸟类,一个是企鹅类,如果鸟是可以飞的,企鹅不会飞,那么企鹅是鸟吗?企鹅可以继承鸟这个类吗?
其实这里是不可以的,我们讨论的是面向对象设计时,也就是说,子类拥有父类所有非private的行为和属性。鸟会飞,但是企鹅不会飞。所以这里企鹅不能以父类–鸟的身份出现,因为前提说所有鸟都可以飞,而企鹅飞不了,所以企鹅不可以继承鸟类。
所以,只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。

正是由于子类型的可替换性才使得使用父类类型的模块在无须修改的情况下就可以扩展

依赖倒转其实可以说是面向对象设计的表示,用哪种语言来编写程序不重要,如果编写时考虑的都是如何针对抽象编程而不是针对细节编程,即程序中所有的依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了

总结

以上就是本文全部内容,本文主要向大家介绍了设计模式中的三大原则-----单一职责原则、开放-封闭原则、依赖倒转原则。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!

最后,大家再见!祝好!我们下期见!

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

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

相关文章

(3dnr)多帧视频图像去噪 (一)

一、多帧视频图像去噪 原理当摄像机每秒捕捉的图像达到60FPS,除了场景切换或者一些快速运动的场 景外,视频信号中相邻的两帧图像内容大部分是相同的。并且视频信号中的噪 声大部分都是均值为零的随机噪声,因此在时间上对视频信号做帧平均&…

从静态到智能:用函数式接口替代传统工具类

在 Java 早期开发中,我们习惯使用**静态实用程序类(Utility Class)**来集中放置一些通用方法,例如验证、字符串处理、数学计算等。这种模式虽然简单直接,但在现代 Java 开发(尤其是 Java 8 引入 Lambda 和函…

免杀伪装 ----> R3进程伪装实战(高阶) ---->培养红队免杀思路

目录 R3进程伪装(免杀技术)高阶技术说明 深入剖析Windows进程规避免杀技术 学习R3进程伪装的必备技能 R3进程伪装的核心知识点与实现步骤 核心知识点 实现步骤 免杀实现步骤 PEB与EPROCESS的深入解析 1. PEB(进程环境块) 2. EPROCESS 3. PEB与…

深度学习——基于卷积神经网络实现食物图像分类(数据增强)

文章目录 引言 一、项目概述 二、环境准备 三、数据预处理 3.1 数据增强与标准化 3.2 数据集准备 四、自定义数据集类 五、构建CNN模型 六、训练与评估 6.1 训练函数 6.2 评估函数 6.3 训练流程 七、关键技术与优化 八、常见问题与解决 九、完整代码 十、总结 引言 本文将详细介…

【开题答辩全过程】以 基于微信小程序的教学辅助系统 为例,包含答辩的问题和答案

个人简介一名14年经验的资深毕设内行人,语言擅长Java、php、微信小程序、Python、Golang、安卓Android等开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。感谢大家的…

【代码解读】Deepseek_vl2中具体代码调用

【代码解读】Deepseek_vl2中具体代码调用 文章目录【代码解读】Deepseek_vl2中具体代码调用DeepseekVLV2Processor解读DeepseekVLV2ForCausalLM - 多模态模型DeepSeek-VL2 Processor的输入格式单样本格式多样本格式DeepSeek-VL2模型的输出形式总结主要输出类型:Deep…

Git 9 ,.git/index.lock 文件冲突问题( .git/index.lock‘: File exists. )

目录 前言 一、问题背景 1.1 问题出现场景 1.2 典型报错信息 1.3 问题影响 二、问题原因分 2.1 Git 的 index 与锁机制 2.2 主要作用 2.3 根本原因 三、解决方案 3.1 确认进程 3.2 手动删除 3.3 再次执行 四、注意事项 4.1 确保运行 4.2 问题排查 4.3 自动化解…

Proteus8 仿真教学全指南:从入门到实战的电子开发利器

在电子设计、单片机课程设计或创客实践中,你是否常因实物采购贵、新手怕烧板、调试排错难而头疼?Proteus8 作为一款 “全能型” EDA 仿真工具,完美解决这些痛点 —— 它集「原理图绘制 PCB 设计 虚拟仿真」于一体,支持 51、STM3…

系统科学:结构、功能与层级探析

摘要本文旨在系统性地梳理和辨析系统科学中的核心概念——结构、功能与层级。文章首先追溯系统思想的理论源流,确立其作为一种超越还原论的整体性研究范式。在此基础上,深度剖析系统结构的内在构成(组分、框架、动态性)、系统层级…

面试官问:你如何看待薪资待遇?

在面试过程中,“你如何看待薪资待遇?”这个问题,是很多面试官都会提出的经典问题之一。虽然表面上看起来是一个简单的提问,但它实则关乎候选人的职业价值观、工作态度以及对自己能力的认知。薪资是工作的重要动力之一,…

HarmonyOS 应用开发新范式:深入剖析 Stage 模型与 ArkUI 最佳实践

好的,请看这篇基于 HarmonyOS (鸿蒙) 最新技术栈的深度技术文章。 HarmonyOS 应用开发新范式:深入剖析 Stage 模型与 ArkUI 最佳实践 引言 随着 HarmonyOS 4、5 的持续演进和未来 6 的规划,其应用开发框架经历了革命性的重构。对于技术开发者…

【Python数据可视化:Matplotlib高级技巧】

Python数据可视化:Matplotlib高级技巧引言在数据科学和分析领域,数据可视化是理解和传达信息的关键工具。Python中最流行的可视化库之一就是Matplotlib。虽然初学者可以快速上手Matplotlib的基础功能,但掌握其高级技巧才能真正发挥这个强大库…

LazyLLM教程 | 第7讲:检索升级实践:亲手打造“更聪明”的文档理解系统!

本节,我们将首先介绍如何评价 RAG 的检索组件,帮助您理解如何衡量 RAG 系统的检索能力。随后,我们会深入探讨几种提升 RAG 系统检索组件效果的策略实现以及对应的效果对比:1.基于 LazyLLM 实现查询重写策略。2.介绍 LazyLLM 中的节…

rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(二十四)窗口颜色、透明度、居中显示

一、窗口颜色和透明度 &#xff08;一&#xff09;效果预览&#xff08;二&#xff09;透明窗体主要代码 use eframe::egui; use egui::Color32;fn main() -> eframe::Result<()> {let options eframe::NativeOptions {viewport: egui::ViewportBuilder::default() …

基于无人机的风电叶片全自动智能巡检:高精度停角估计与细节优先曝光调控技术

【导读】 本文致力于解决一个非常实际的工业问题&#xff1a;如何利用无人机&#xff08;UAV&#xff09;全自动、高效、可靠地检查风力涡轮机叶片。叶片是风力发电机组中最昂贵且易损的部件之一&#xff0c;定期检查至关重要。然而&#xff0c;当前的技术在自动化过程中面临几…

腾讯云上有性能比较强的英伟达GPU

腾讯云上有性能比较强的英伟达GPU A100&#xff0c;虽然落后3~4代&#xff0c;但是估计是最强的英伟达GPU了。

AI任务相关解决方案13-AI智能体架构方案(意图识别+多任务规划+MCP+RAG)与关键技术深度解析研究报告,以及实现代码

文章目录 1. 总体技术方案 2. 生成式大模型(LLM):Data Agent的大脑 3. 意图识别:准确理解用户意图 3.1 基于BERT的微调方法 3.2 基于大语言模型(LLM)的零样本/少样本方法 4. 多任务规划:提升架构的灵活性 4.1 任务分解与规划 4.2 多智能体协作规划 4.3 基于强化学习的规划方…

每日五个pyecharts可视化图表日历图和箱线图:从入门到精通

&#x1f4ca; 本文特色&#xff1a;从零开始掌握日历图和箱线图可视化技巧&#xff0c;包含多个完整实例、核心配置项解析和实用场景指南&#xff0c;助您快速构建专业数据可视化图表。pyecharts源码 目录什么是日历图和箱线图&#xff1f;&#x1f4c5; 日历图&#xff08;Ca…

在本地获取下载chrome,然后离线搬运到 ECS

场景&#xff1a; 阿里云 ECS 无Y网&#xff0c;无法直接拉取 storage.googleapis.com。因此需先在本地里拿到直链并下载&#xff0c;再上传到 ECS。 注&#xff1a; 这个链接是显示近期的几个版本 https://googlechromelabs.github.io/chrome-for-testing/ 这个链接是所有版…

小土堆目标检测笔记

文章目录1 什么是目标检测2 目标检测常见的数据集2.1 目标检测数据集2.2 目标检测数据集的标注2.3 目标检测工具介绍3 数据集的标注3.1 VOC数据集标注3.2 加载数据集1 什么是目标检测 希望计算机在视频或图像中定位并识别我们感兴趣的目标 定位&#xff1a;找到目标在图像中的…