C++设计模式---面向对象原则

面向对象设计原则

原则的目的:高内聚,低耦合

1. 单一职责原则

类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。

2. 开闭原则

对扩展开放,对修改关闭;增加功能是通过增加代码来实现的,而不是去修改源代码。

#include<iostream>
using namespace std;//开闭原则
//对扩展开放,对修改关闭;增加功能是通过增加代码来实现的,而不是去修改源代码//写一个抽象类
class AbstractCaculator
{
public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;
};//加法计算类
class AddCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;}public:int mA;int mB;
};//减法计算器
class SubCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;}public:int mA;int mB;
};//乘法计算器
class MolCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;}public:int mA;int mB;
};//取模计算器	通过增加代码来实现
class MulCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA % mB;}public:int mA;int mB;
};void test01()
{AbstractCaculator* caculator = new AddCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;delete caculator;caculator = new SubCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;
}int main()
{test01();return 0;
}

3. 里氏代换原则

任何抽象类出现的地方都可以用他的实现类进行替换,实际就是虚拟机制,语言级别实现面向对象功能。 

4. 依赖倒转原则

依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。 

传统方式:

#include<iostream>
using namespace std;//银行工作人员
class BankWorker
{public:void saveService(){cout << "办理存款业务..." << endl;}void payService(){cout << "办理支付业务..." << endl;}void tranferService(){cout << "办理转账业务..." << endl;}
};//中层模块
void doSaveBussiness(BankWorker* worker) {worker->saveService();
}void doPayBussiness(BankWorker* worker) {worker->payService();
}void doTranferBussiness(BankWorker* worker) {worker->tranferService();
}void test04() {BankWorker* worker = new BankWorker;doSaveBussiness(worker);  //办理存款业务doPayBussiness(worker); //办理支付业务doTranferBussiness(worker); //办理转账业务
}int main()
{test04();return 0;
}

依赖倒转原则: 

#include<iostream>
using namespace std;//银行工作人员
class AbstractWorker
{
public:virtual void doBusiness() = 0;
};//专门办理存款业务的工作人员
class SaveBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理存款业务..." << endl;}
};//专门办理支付业务的工作人员
class PayBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理支付业务..." << endl;}
};//专门办理转账业务的工作人员
class TransferBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理转账业务..." << endl;}
};//中层业务
void doNewBussiness(AbstractWorker* worker)
{worker->doBusiness();
}void test04_1()
{AbstractWorker* transfer = new TransferBankWorker;doNewBussiness(transfer);
}int main()
{test04_1();return 0;
}

5. 接口隔离原则

        不应该强迫用户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去。 

6. 迪米特法则(最少知识原则) 

        一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节,这样当一个模块内部的实现发生改变时,不会影响其他模块的使用。(黑盒原理)

#include<iostream>
#include<string>
#include<vector>
using namespace std;//迪米特法则---最少知识原则
class AbstractBuilding
{
public:virtual void sale() = 0;virtual string getQuality() = 0;
};//楼盘A
class BuildingA : public AbstractBuilding
{
public:BuildingA(){m_Quality = "高品质";}virtual void sale(){cout << "楼盘A" << m_Quality << "被售卖!" << endl;}virtual string getQuality(){return m_Quality;}public:string m_Quality;
};//楼盘B
class BuildingB : public AbstractBuilding
{
public:BuildingB(){m_Quality = "低品质";}virtual void sale(){cout << "楼盘B" << m_Quality << "被售卖!" << endl;}virtual string getQuality(){return m_Quality;}
public:string m_Quality;
};//客户端
void test02()
{BuildingA* ba = new BuildingA;if (ba->m_Quality == "高品质"){ba->sale();}BuildingB* bb = new BuildingB;if (bb->m_Quality == "低品质"){bb->sale();}
}//中介类
class Mediator
{
public:Mediator(){AbstractBuilding* building = new BuildingA;vBuilding.push_back(building);building = new BuildingB;vBuilding.push_back(building);}//对外提供接口AbstractBuilding* findMyBuilding(string quality){for (vector<AbstractBuilding*>::iterator it = vBuilding.begin(); it != vBuilding.end(); it++)if ((*it)->getQuality() == quality){return *it;}return NULL;}~Mediator(){for (vector<AbstractBuilding *>::iterator it = vBuilding.begin();it != vBuilding.end();it++)if (*it != NULL){delete* it;}}public:vector<AbstractBuilding *> vBuilding;
};void test02_1()
{Mediator* meidator = new Mediator;AbstractBuilding* building = meidator->findMyBuilding("高品质");if (building != NULL){building->sale();}else{cout << "没有符合条件的楼盘!" << endl;}
}int main()
{test02();test02_1();return 0;
}

7. 合成复用原则

如果使用继承,会导致父类的任何变换都可能影响到子类的行为。

如果使用对象组合,就降低了这种依赖关系。
对于继承和组合,优先使用组合。

#include<iostream>
using namespace std;//抽象车
class AbstructCar
{
public:virtual void run() = 0;
};//大众车
class Dazhong :public AbstructCar
{
public:virtual void run(){cout << "大众车启动" << endl;}
};//拖拉机
class Tuolaji :public AbstructCar
{
public:virtual void run(){cout << "拖拉机启动" << endl;}
};//针对具体类,不适用继承
#if 0
class Person :public Tuolaji
{
public:void Douofeng(){run();}
};class PersonB :public Dazhong
{
public:void Douofeng(){run();}
};
#endif//可以使用组合
class Person
{
public:void setCar(AbstructCar *car){this->car = car;}void Doufeng(){this->car->run();if (this->car != NULL){delete this->car;this->car = NULL;}}public:AbstructCar* car;
};void test03()
{Person* p = new Person;p->setCar(new Dazhong);p->Doufeng();p->setCar(new Tuolaji);p->Doufeng();delete p;
}//继承和组合 优先使用组合
int main()
{test03();return 0;
}

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

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

相关文章

【linux特殊符号】

文章目录 学习目标一、Linux的特殊符号1.系统变量2.引号 总结 学习目标 1.学会查看系统变量 2.学会各种引号 3.一、Linux的特殊符号 1.系统变量 windows系统变量&#xff1a;echo %path% linux系统变量&#xff1a;echo $PATH2.引号 " " 双引号&#xff0c;换行…

如何基于springboot构建cas最新版源码?

环境准备 下载JDK21 https://download.oracle.com/java/21/archive/jdk-21.0.2_windows-x64_bin.zip下载gradle 8.5并配置环境变量 https://gradle.org/next-steps/?version8.5&formatbin下载项目git clone http://gitlab.ruishan.cc/meta/anka-authentication.git 开始…

web前端项目已有阿里巴巴图标基础上,再次导入阿里巴巴图标的方法

如果是第一次导入阿里巴巴图标请参考: vue项目引入阿里云图标_vue引用阿里云图标fontclass-CSDN博客 本文主要想讲在项目原有阿里巴巴图标基础上,再次导入阿里巴巴图标的解决办法: 1.iconfont.json对应修改就行,这个简单一看就明白; 2.iconfont.js主要改动<symbol><…

Ansible自动化运维中的file文件模块模块应用详解

作者主页&#xff1a;点击&#xff01; Ansible专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年5月21日15点21分 &#x1f4af;趣站推荐&#x1f4af; 前些天发现了一个巨牛的&#x1f916;人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xf…

【Java笔记】第8章:面向对象的三大特性(封装、继承、多态)

前言1. 三大特性概述2. 封装3. 继承4. 多态结语 #include<GUIQU.h> int main { 上期回顾:【Java笔记】第7章&#xff1a;面向对象 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【Java学习】 return 一键三连; } 前言 各位小伙伴大家好&#xff01;上期小编给大家…

网络工程师备考1——基础学习

认识设备 1 交换机 一、什么是交换机&#xff1f; 实现不同电脑之间数据的转发 换机是一种用于电(光)信号转发的网络设备。 它可以为接入交换机的任意两个网络节点提供独享的电信号通路。最常见的交换机是以太网交换机。交换机工作于OSI参考模型的第二层&#xff0c;即数据…

使用 Supabase 的 Realtime + Storage 非常方便呢

文章目录 &#xff08;一&#xff09;Supabase&#xff08;二&#xff09;Realtime&#xff08;消息&#xff09;&#xff08;2.1&#xff09;Python 消息订阅&#xff08;2.2&#xff09;JavaScript 消息订阅 &#xff08;三&#xff09;Storage&#xff08;存储&#xff09;&…

Linux:Ubuntu修改root密码

Linux&#xff1a;Ubuntu修改root密码 修改默认grub配置文件 rootshanxin:~# vim /etc/default/grub# 主要修改内容如下&#xff1a;GRUB_DEFAULT0 #GRUB_TIMEOUT_STYLEhidden 注释这一行 GRUB_TIMEOUT5 # 将这一行的时间改为5秒进行开启启动的grub文件的复写 rootshanxin:~…

芯课堂 | UI Creator 物理键盘移植指南

LVGL提供输入设备的种类一共有5种&#xff0c;分别是&#xff1a;touchpad&#xff08;触摸板&#xff09;、mouse&#xff08;鼠标&#xff09;、keypad&#xff08;键盘&#xff09;、encoder&#xff08;编码器&#xff09;、button&#xff08;外部按键&#xff09;。而基于…

如何成为一个专业的AI产品经理?

可以找专业的老师带。 可以找专业的内容学。 可以多遇挫折并快速学习&#xff0c;屡败屡战&#xff0c;笔者本人从业AI十年有余&#xff0c;吃了不少苦&#xff0c;有过很多或成功或失败的经历。 成为一个专业的AI产品经理需要一系列专业知识和技能的积累&#xff0c;以及在…

基于Matlab卷积神经网络(CNN)人脸识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别技术作为计算机视觉领域的一个重要分支&#xff0c;已经广泛应用于安全监控、身份验证…

FreeRTOS学习——FreeRTOS队列(下)之队列创建

本篇文章记录我学习FreeRTOS队列创建的知识。主要分享队列创建需要使用的初始化函数、队列复位函数。 需要进一步了解FreeRTOS队列的相关知识&#xff0c;读者可以参考以下文章&#xff1a; FreeRTOS学习——FreeRTOS队列&#xff08;上&#xff09;_freertos 单元素队列-CSDN博…

【hackmyvm】Slowman靶机

文章目录 主机探测端口探测FTP匿名登录 目录探测hydra爆破mysql爆破zip------fcrackzip爆破密码-----john提权 主机探测 ┌──(root㉿kali)-[/home/kali] └─# fping -ag 192.168.9.1/24 2>/dev/null 192.168.9.221 主机192.168.9.224 靶机端口探测 ┌──(roo…

【教程】Linux 安装 kkFileView 文档在线预览项目 及优化

【教程】Linux 安装 kkFileView 文档在线预览项目 官网 kkFileView - 在线文件预览 (keking.cn) 安装包 可以直接下载成品 也可以下载source 源码 自己编译 kkFileView 发行版 - Gitee.com 打开IDEA 然后先clear 再install 然后在 file-online-preview\server\target 目录…

WordPress插件Disable WP REST API,可根据是否登录来禁用REST API

前面跟大家分享了代码版禁用WordPress REST API的方法&#xff08;详见『WordPress4.7以上版本如何禁用JSON REST API&#xff1f;』&#xff09;&#xff0c;不过有些站长不太敢折腾自己的网站代码&#xff0c;那么建议试试这款Disable WP REST API&#xff0c;它可以&#xf…

小结5:朗读练习第二段

五、朗读练习2 2024-5-6始&#xff0c;5-14终&#xff0c;5-15写。 我渐渐体会到一些朗读的乐趣。但我还要考研&#xff0c;要写作业、期末考试。如果是在大一该多好。我可以就这样一天一天的写下去&#xff0c;慢慢地有一些自己的作品&#xff0c;还能录视频发到b站上。 上一篇…

通过修改物理内存实现跨进程内存读写

习一下利用修改物理内存来跨进程内存读写 系统&#xff1a;win10 21h1 x64 编译环境: vs2022 详情见附录 基础 虚拟地址转物理地址 虚拟地址也称线性地址&#xff0c;一个线性地址进程的DirBase地址可以转换成物理地址。先来看线性地址的含义 在x64体系中只实现了48位的virtu…

刷题之从前序遍历与中序遍历序列构造二叉树(leetcode)

从前序遍历与中序遍历序列构造二叉树 前序遍历&#xff1a;中左右 中序遍历&#xff1a;左中右 前序遍历的第一个数必定为根节点&#xff0c;再到中序遍历中找到该数&#xff0c;数的左边是左子树&#xff0c;右边是右子树&#xff0c;进行递归即可。 #include<vector>…

Juniper查看并调整策略顺序

1.查看安全策略 >show security policies 顺序就是按照显示出来的顺序&#xff0c;与Index无关&#xff0c;从上到下匹配 2. 调整防火墙策略 #insert security policies from-zone CAMERAS to-zone INTERNET policy CAMERAS-to-NTP before policy CAMERAS-to-INTERNET …

操作系统3_作业与处理机调度

操作系统3_作业与处理机调度 文章目录 操作系统3_作业与处理机调度1. 作业的概念与组成2. 作业的建立及状态3. 处理机调度相关概念3.1 调度级别3.2 调度队列模型3.3 选择准则4. 作业调度与进程调度5. 典型处理机调度算法5.1 先来先服务算法FCFS5.2 短作业优先算法SJF5.3 优先级…