设计模式三原则

1.1单一职责原则

        C++ 面向对象三大特性之一的封装指的就是将单一事物抽象出来组合成一个类,所以我们在设计类的时候每个类中处理的是单一事物而不是某些事物的集合。

        设计模式中所谓的单一职责原则,就是对一个类而言,应该仅有一个引起它变化的原因,其实就是将这个类所承担的职责单一化,如果一个类承担的职责过多,就等于把这些职责耦合到了一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致设计变得脆弱,当变化发生时,设计会遭受到意想不到的破坏。

        软件设计真正要做的事情就是,发现根据需求发现职责,并把这些职责进行分离,添加新的类,给当前类减负,越是这样项目才越容易维护。

1.2开放封闭原则

        开放 – 封闭原则说的是软件实体(类、模块、函数等)可以扩展,但是不可以修改。也就是说对于扩展是开放的,对于修改是封闭的。

        该原则是程序设计的一种理想模式,在很多情况下无法做到完全的封闭。但是作为设计人员,应该能够对自己设计的模块在哪些位置产生何种变化了然于胸,因此需要在这些位置创建抽象类来隔离以后发生的这些同类变化(其实就是对多态的应用创建新的子类并重写父类虚函数,用以更新处理动作)。此处的抽象类,其实并不等价于 C++ 中完全意义上是抽象类(需要有纯虚函数),这里所说的抽象类只需要包含虚函数(纯虚函数或非纯虚函数)能够实现多态即可

        开放 – 封闭原则是面向对象设计的核心所在,这样可以给我们设计出的程序带来巨大的好处,使其可维护性、可扩展性、可复用性、灵活性更好

1.3依赖倒转原则(对多态的典型应用)

关于依赖倒转原则,对应的是两条非常抽象的描述:

1.高层模块不应该依赖低层模块,两个都应该依赖抽象。

 2.抽象不应该依赖细节,细节应该依赖抽象。

先用人话解释一下这两句话中的一些抽象概念:

  • 高层模块:可以理解为上层应用,就是业务层的实现,编写的应用程序
  • 低层模块:可以理解为底层接口,比如封装好的 API、动态库等
  • 抽象:指的就是抽象类或者接口,在 C++ 中没有接口概念(Java里有),只有抽象类(在设计模式里的抽象类没有那么严格,可以为虚函数或纯虚函数),C++中定义接口的方法是在父类定义虚函数,在子类中重写虚函数。

举一个高层模块依赖低层模块的例子:

        大聪明的项目组接了一个新项目,低层使用的是 MySql 的数据库接口,高层基于这套接口对数据库表进行了添删查改,实现了对业务层数据的处理。而后由于某些原因,要存储到数据库的数据量暴增,所以更换了 Oracle 数据库,由于低层的数据库接口变了,高层代码的数据库操作部分是直接调用了低层的接口,因此也需要进行对应的修改,无法实现对高层代码的直接复用,大聪明欲哭无泪。

        解决方法是高层和底层代码之间设计好抽象类和抽象类子类,写好调用MySQL的抽象子类,当底层换成Oracle数据库时,只需要增加调用Oracle的抽象子类,从而减少工作量。        

        通过上面的例子可以得知,当依赖的低层模块变了就会牵一发而动全身,如果这样设计项目架构,对于程序猿来说,其工作量无疑是很重的。如果要搞明白这个案例的解决方案以及抽象和细节之间的依赖关系,需要先了解另一个原则——里氏代换原则

里氏代换原则

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

关于这个原理的应用其实也很常见,比如在 Qt 中,所有窗口类型的类的构造函数都有一个 QWidget* 类型的参数(QWidget 类是所有窗口的基类),通过这个参数指定当前窗口的父对象。虽然参数是窗口类的基类类型,但是我们在给其指定实参的大多数时候,指定的都是子类的对象,其实也就是相当于使用子类类型替换掉了它们的父类类型。

上面在讲依赖倒转原则的时候说过,抽象不应该依赖细节,细节应该依赖抽象。也就意味着我们应该对细节进行封装,在 C++ 中就是将其放到一个抽象类中(C++ 中没有接口,不能像 Java 一样封装成接口),每个细节就相当于上面例子中的哺乳动物的一个特性,这样一来这个抽象的哺乳动物类就成了项目架构中高层和低层的桥梁,将二者整合到一起。

  • 抽象类中提供的接口是固定不变的
  • 低层模块是抽象类的子类,继承了抽象类的接口,并且可以重写这些接口的行为
  • 高层模块想要实现某些功能,调用的是抽象类中的函数接口,并且是通过抽象类的父类指针引用其子类的实例对象(用子类类型替换父类类型),这样就实现了多态。

 基于依赖倒转原则将项目的结构换成上图的这种模式之后,低层模块发生变化,对应高层模块是没有任何影响的,这样程序猿的工作量降低了,代码也更容易维护(说白了,依赖倒转原则就是对多态的典型应用)。

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

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

相关文章

怎么借助ChatGPT处理数据结构的问题

目录 使用ChatGPT进行数据格式化转换 代码示例 ChatGPT格式化数据提示语 代码示例 批量格式化数据提示语 代码示例 ChatGPT生成的格式化批处理代码 使用ChatGPT合并不同数据源的数据 合并数据提示语 自动合并数据提示语 ChatGPT生成的自动合并代码 结论 数据合并是…

RT-Thread内核学习

内核框架 内核是操作系统最基础也是最重要的部分,内核处于硬件层之上,内核部分包括内核库、实时内核实现。 内核库是为了保证内核能够独立运行的一套小型的类似C库的函数实现子集。这部分根据编译器不同自带C库的情况也会不同。 当使用GNU GCC编译器时&…

波奇学C++:stl的list模拟实现

list是双向带头链表。所以迭代器end()相当于哨兵卫的头。 list不支持和[]重载&#xff0c;原因在于list空间不是连续的&#xff0c;和[]的代价比较大。 访问第n个节点&#xff0c;只能用for循环&#xff0c;来实现 list<int> l; l.push_back(0); l.push_back(1); l.pu…

hive-列转行

转成 select customer_code,product_type from temp.temp_xx LATERAL VIEW explode(SPLIT(product_types,,)) table_tmp AS product_type where customer_code K100515182

C#开发WinForm之DataGridView开发

前言 DataGridView是开发Winform的一个列表展示&#xff0c;类似于表格。学会下面的基本特征用法&#xff0c;再辅以经验&#xff0c;基本功能开发没问题。 1.设置 DataGridView表格行首为序号索引, //设置 DataGridView表格行首为序号索引private void dataGridView1_RowPost…

python实现卡尔曼滤波代码详解

Kalman滤波算法的原理可以参考&#xff1a; 卡尔曼滤波理解 python中filterpy库中实现了各种滤波算法&#xff0c; 其中就包括了kalman滤波算法。 具体实现代码&#xff1a; https://github.com/rlabbe/filterpy/blob/master/filterpy/kalman/kalman_filter.py 本文针对该代码…

数据结构——布隆计算器

文章目录 1.什么是布隆过滤器&#xff1f;2.布隆过滤器的原理介绍3.布隆过滤器使用场景4.通过 Java 编程手动实现布隆过滤器5.利用Google开源的 Guava中自带的布隆过滤器6.Redis 中的布隆过滤器6.1介绍6.2使用Docker安装6.3常用命令一览6.4实际使用 1.什么是布隆过滤器&#xf…

骨传导耳机对大脑有影响吗?骨传导耳机有什么副作用

先上结论&#xff0c;骨传导耳机对大脑没有影响。骨传导耳机使用的是骨传导技术&#xff0c;声音是通过头骨骨头和颌骨给内耳传递的&#xff0c;而不是通过传统的空气传播。 简单来说&#xff0c;骨传导技术使用人类骨骼结构和声学原理来传递声音&#xff0c;这种现象我们也很常…

最新Burp Suite入门技术

Burp Suite的安装 Burp Suite是一款集成化的渗透测试工具&#xff0c;包含了很多功能&#xff0c;可以帮助我们高效地完成对Web应用程序的渗透测试和安全检测。 Burp Suite由Java语言编写&#xff0c;Java自身的跨平台性使我们能更方便地学习和使用这款软件。不像其他自动化测…

vue3 基础知识 (组件之间的通信 and vuex) 02

侬好哇 &#xff01;&#x1f60d; 文章目录 一、组件的通信 &#xff08;父传子&#xff09;二、非 Prop 的Attribute (属性&#xff09;三、组件的通信 &#xff08;子传父&#xff09;四、非父子组件的相互通信&#xff08;Provide/Inject&#xff09;五、非父子组件的相互通…

顺序表之初

欢迎来到我的&#xff1a;世界 希望作者的文章对你有所帮助&#xff0c;有不足的地方还请指正&#xff0c;大家一起学习交流 ! 目录 线性表简介顺序表定义动态顺序表的初始化尾插头插Cheak 判断是否增容尾删&#xff1a;头删&#xff1a;打印在pos位置前插入x删除pos位置的值查…

Python学习笔记_实战篇(二)_django多条件筛选搜索

多条件搜索在很多网站上都有用到&#xff0c;比如京东&#xff0c;淘宝&#xff0c;51cto&#xff0c;等等好多购物教育网站上都有&#xff0c;当然网上也有很多开源的比楼主写的好的多了去了&#xff0c;仅供参考&#xff0c;哈哈 先来一张效果图吧&#xff0c;不然幻想不出来…

浅谈小程序开源业务架构建设之路

一、业务介绍 1.1 小程序开源整体介绍 百度从做智能小程序的第一天开始就打造真正开源开放的生态&#xff0c;我们的愿景是&#xff1a;定义移动时代最佳体验&#xff0c;建设智能小程序行业标准&#xff0c;打破孤岛&#xff0c;共建开源、开放、繁荣的小程序行业生态。百度智…

电子电路学习笔记之SA1117BH-1.2TR——LDO低压差线性稳压器

关于LDO调节器&#xff08;Low Dropout Regulator&#xff09;是一种电压稳压器件&#xff0c;常用于电子设备中&#xff0c;用于将高电压转换为稳定的低电压。它能够在输入电压和输出电压之间产生较小的差异电压&#xff0c;因此被称为"低压差稳压器"。 LDO调节器通…

设计模式之职责链模式(ChainOfResponsibility)的C++实现

1、职责链模式的提出 在软件开发过程中&#xff0c;发送者经常发送一个数据请求给特定的接收者对象&#xff0c;让其对请求数据进行处理&#xff08;一个数据请求只能有一个对象对其处理&#xff09;。如果发送的每个数据请求指定特定的接收者&#xff0c; 将带来发送者与接收…

【LeetCode】1448.统计二叉树中好节点的数目

题目 给你一棵根为 root 的二叉树&#xff0c;请你返回二叉树中好节点的数目。 「好节点」X 定义为&#xff1a;从根到该节点 X 所经过的节点中&#xff0c;没有任何节点的值大于 X 的值。 示例 1&#xff1a; 输入&#xff1a;root [3,1,4,3,null,1,5] 输出&#xff1a;4 …

【MOS管的作用和工作原理】

数电/模电知识学习与分享001 MOS管的作用和工作原理1、MOS管基本概念2、MOS管基本原理3、MOS管广泛作用4、MOS管特点4、参考文献 MOS管的作用和工作原理 1、MOS管基本概念 MOS管&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff09;是一种常用的半导体…

python AI绘图教程

前提 1.安装python 2.安装git 步骤 下载stable-diffusion-webui项目&#xff08;链接&#xff1a;GitHub - AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI&#xff09; git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git 安装st…

【Go Web 篇】Go 语言进行 Web 开发:构建高性能网络应用

随着互联网的快速发展&#xff0c;Web 开发已经成为了软件开发领域中不可或缺的一部分。随之而来的是对于更高性能、更高效的网络应用的需求。在这个领域&#xff0c;Go 语言因其并发性能、简洁的语法以及丰富的标准库而备受关注。本篇博客将深入探讨如何使用 Go 语言进行 Web …

centos7设置静态IP地址

安装完成系统后&#xff0c;接下来就是配置静态IP地址&#xff0c;如下&#xff1a; 进入编辑模式vim /etc/sysconfig/network-scripts/ifcfg-ens33 文件名不一定是ifcfg-ens33&#xff0c;到/etc/sysconfig/network-scripts下面找下是哪个文件 修改 &#xff1a; BOOTPROTO…