设计模式的学习
OO:Object-Oriented
面向对象
---
《Head First设计模式》
这本书是用java写的,我是写C++的,用C++来写相关的代码
---
p2(第二页)
#ifndef DUCK_H
#define DUCK_H/*** @brief The Duck class 鸭子类*/
class Duck
{
public:Duck();/*** @brief quack 呱呱叫* 所有的鸭子都会呱呱叫* 所以在父类中实现这部分代码*/void quack();/*** @brief swim 游泳* 所有的鸭子都会游泳* 所以在父类中实现这部分代码*/void swim();/*** @brief display 展示鸭子的外观* 每种鸭子的外观特点不同,需要在子类中进行实现* 所以这里是虚函数*/virtual void display();
};#endif // DUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display();
};#endif // MALLARDDUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display();
};#endif // MALLARDDUCK_H
---
现在需要添加需求:一部分鸭子会飞。
如果直接在基类中添加fly(),那么意味着所有的鸭子都会飞。(所有的子类都拥有了fly() )
而橡皮鸭子是不会飞的。
---
当涉及“维护”时,为了复用目的而使用继承,并不是完美的。
---
如果子类把fly()方法覆盖掉呢?
可以,但如果再加入一种不会飞的鸭子,那么需要重新再覆盖fly()方法。
void fly()
{//覆盖,什么事都不做
}
每多一种鸭子,就需要覆盖一次fly()方法。
------
而有些鸭子不会飞,也不会叫。
---
希望找到一种建立软件的方法,让我们可以用一种对既有的代码影响最小的方式来修改软件。
这样我们就可以花较少时间重做代码,而让程序去做更酷的事。
---
继承不能很好地解决问题,因为鸭子的行为在子类中不断地改变,并且让所有的子类都有这些行为是不恰当的。
Flyable和Quackable接口一开始似乎还不错,但继承接口无法达到代码的复用。
当需要修改某个行为时,需要在定义此行为的类中修改它。
---
设计原则:
找出应用中可能需要变化之处,把它们独立出来,不要和不需要变化的代码混在一起。
---
努力让系统中的某部分改变不会影响其他部分。
---
设计原则:
针对接口编程,而不是针对实现编程。
---
简单的多态例子:
有一个抽象类Animal,两个具体的实现:Dog和Cat继承自Animal
针对实现编程:
Dog d = new Dog();
d.bark();
针对接口编程:
Animal * animal = new Dog();
animal.makeSound();
子类实例化的动作不再需要在代码中硬编码,而是在运行时才指定具体实现的对象,
进一步封装:
a = getAnimal();
a.makeSound();
我们不关心实际的子类型是什么,我们只关心它知道如何正确地调用makeSound()。
---
#ifndef FLYBEHAVIOR_H
#define FLYBEHAVIOR_H
#include <QDebug>
/*** @brief The FlyBehavior class 飞行行为*/
class FlyBehavior
{
public:FlyBehavior(){}virtual void fly(){}
};/*** @brief The FlyWithWings class 用翅膀飞行*/
class FlyWithWings : public FlyBehavior
{
public:FlyWithWings(){}virtual void fly(){qDebug()<<"用翅膀飞行";}
};/*** @brief The FlyNoWay class 不会飞行*/
class FlyNoWay : public FlyBehavior
{
public:FlyNoWay(){}virtual void fly(){qDebug()<<"不会飞行";}
};#endif // FLYBEHAVIOR_H
#ifndef FLYBEHAVIOR_H
#define FLYBEHAVIOR_H
#include <QDebug>
/*** @brief The FlyBehavior class 飞行行为*/
class FlyBehavior
{
public:FlyBehavior(){}virtual void fly(){}
};/*** @brief The FlyWithWings class 用翅膀飞行*/
class FlyWithWings : public FlyBehavior
{
public:FlyWithWings(){}virtual void fly(){qDebug()<<"用翅膀飞行";}
};/*** @brief The FlyNoWay class 不会飞行*/
class FlyNoWay : public FlyBehavior
{
public:FlyNoWay(){}virtual void fly(){qDebug()<<"不会飞行";}
};#endif // FLYBEHAVIOR_H
关键在于:
鸭子现在会将飞行和呱呱叫的动作“委托”别人处理,而不是使用定义在Duck类或子类内的呱呱叫和飞行方法。
#ifndef DUCK_H
#define DUCK_H#include "flybehavior.h"
#include "quackbehavior.h"
/*** @brief The Duck class 鸭子类*/
class Duck
{
public:Duck();FlyBehavior * flyBehavior;QuackBehavior * quackBehavior;void performQuack(){quackBehavior->quack();}void performFly(){flyBehavior->fly();}/*** @brief display 展示鸭子的外观* 每种鸭子的外观特点不同,需要在子类中进行实现* 所以这里是虚函数*/virtual void display(){}
};#endif // DUCK_H
#ifndef MALLARDDUCK_H
#define MALLARDDUCK_H#include "duck.h"
/*** @brief The MallardDuck class 绿头鸭*/
class MallardDuck : public Duck
{
public:MallardDuck();virtual void display(){}
};#endif // MALLARDDUCK_H
#include "mallardduck.h"MallardDuck::MallardDuck()
{flyBehavior = new FlyWithWings();quackBehavior = new MuteQuack();
}
MallardDuck mallardDuck;mallardDuck.performFly();mallardDuck.performQuack();

---
通过基类的指针析构子类时,会出现内存泄漏吗?
如果不希望内存泄漏,析构函数必须定义为虚函数。
---
设计原则:
多用组合,少用继承。
使用组合建立系统具有很大的弹性,不仅可将算法族封装成类,更可以“在运行时动态地改变行为”。
策略模式:
定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
上面的鸭子示例中:可以在运行时动态地切换鸭子相关的行为(算法)(用翅膀飞,不会飞)
------
设计是一门艺术,总是有许多可取舍的地方。
设计大师关心的是建立弹性的设计,可以维护,可以应付变化。
相关文章:
设计模式的学习
OO:Object-Oriented 面向对象 --- 《Head First设计模式》 这本书是用java写的,我是写C的,用C来写相关的代码 --- p2(第二页) #ifndef DUCK_H #define DUCK_H/*** brief The Duck class 鸭子类*/ class Duck { public:D…...
wordpress发邮件SMTP服务器配置步骤指南?
wordpress发邮件功能如何优化?怎么用wordpress发信? 由于WordPress默认的邮件发送功能可能不够稳定,配置SMTP服务器成为了许多网站管理员的选择。AokSend将详细介绍如何在WordPress中配置SMTP服务器,以确保邮件能够顺利发送。 w…...
胤娲科技:机械臂「叛逃」记——自由游走,再悄然合体
夜深人静,你正沉浸在梦乡的前奏,突然意识到房间的灯还亮着。此刻的你,是否幻想过有一只无形的手,轻盈地飘过,帮你熄灭那盏碍眼的灯? 又或者,你正窝在沙发上,享受电视剧的紧张刺激&am…...
分布式事务讲解 - 2PC、3PC、TCC
分布式事务讲解 - 2PC、3PC、TCC 前置知识 BASE理论: BASE是Basically Availbale(基本可用)、Soft state(软状态)、Eventually consistent(最终一致性)三个词语的缩写。BASE理论是对CAP理论中AP的一个扩展,通过牺牲强一致性来获得可用性,当…...
前端基础面试题·第四篇——Vue(其二)
1.Vue中路由传参 1.params传参 params 传参是通过URL路径来传递参数,这种方式传递的参数是必选的。这种传参方式需要在路由配置时在路由路径位置提前指定参数。 路由配置 const router new VueRouter({routes: [{path: /user/:id, // 这里的:id就是参数name: u…...
PHP反射
文章目录 介绍基本用法基本的反射示例1. 反射类2. 反射方法3. 反射属性4.反射全局函数5.反射函数的参数 优势和注意事项优势:注意事项: 介绍 PHP反射是一种强大的机制,允许在运行时检查类、接口、方法、属性等的结构和元数据。它可以用于许多…...
Gated Transformer Networks for Multivariate Time Series Classification
博客贡献人 徐宁 作者 Minghao Liu , Shengqi Ren , Siyuan Ma , Jiahui Jiao , Yizhou Chen , Zhiguang Wang(Facebook AI) and Wei Song∗ 标签 多元时间序列分类,Transformer,门控 摘要 用于时间序列分类的深度学习模型(主要是卷积网…...
这一次,AI真的能帮你实现职场跃迁
你有没有想过: AI不仅能帮你实现工作提效 还能帮你实现职场跃迁! 根据行业报告,近年来**AIGC(AI Generated Content)**领域岗位数量井喷式增长,AI大模型产品经理作为连接技术与市场的桥梁,正扮…...
Python绘制--绘制心形曲线
今天,我们将通过Python代码来绘制一个心形曲线,这是一个经典的数学表达。 一、心形曲线的数学原理 心形曲线,也被称为心脏曲线,是一个代数曲线,可以通过参数方程定义。其数学表达式如下: x16sin3(t)x16…...
初识Linux · 自主Shell编写
目录 前言: 1 命令行解释器部分 2 获取用户命令行参数 3 命令行参数进行分割 4 执行命令 5 判断命令是否为内建命令 前言: 本文介绍是自主Shell编写,对于shell,即外壳解释程序,我们目前接触到的命令行解释器&am…...
海报设计模板免费的好用吗?活动海报排版技巧轻松get
虽然今年所有的法定节假日已经过完了,但对于电商打工族来说,需要制作活动海报的节日,还有很多吧...... 刚听到小道消息,说是今年的双十一,从十月十四号就开始预热了! 怎么样,大家的预热活动海…...
【Linux基础】03 Linux环境基础开发工具使用
1. yum ——软件包管理器 yum 是我们 Linux 预装的一个指令,搜索、下载、、安装对应的软件 yum 相当于 Linux 的应用商店! 安装与卸载 yum list | grep command 通过 yum list 命令可以罗列出当前一共有哪些软件包. 由于包的数目可能非常之多, 这里我…...
【CSS】flex: 1; 的意思
在 Flexbox 布局中,flex: 1; 是一个简写属性,它表示弹性容器中的子元素如何分配可用空间。flex: 1 意味着该元素可以根据剩余的空间进行扩展,占据相应的比例。具体来说,flex: 1; 是 flex-grow、flex-shrink 和 flex-basis 这三个属…...
C++ 3D冒险游戏开发案例
3D冒险游戏的C开发案例,包括游戏设计、实现细节、图形渲染、音效处理等内容。 3D冒险游戏开发案例 一、游戏设计 游戏概述 游戏名称:“探索者的传奇”类型:3D冒险游戏目标:玩家控制角色在一个开放的世界中探索、解谜、战斗并完成…...
【AIGC】Exa AI 要做 AI 领域的 Google
又一个AI搜索引擎诞生:Exa AI。 与其他旨在取代谷歌的AI驱动搜索引擎不同,Exa的目标是创建一个专门为AI设计的搜索工具。 Exa的使命: 互联网包含人类的集体知识,但目前的搜索体验更像在垃圾场中导航,而非在知识图书馆中漫游。核…...
YOLOv8 基于MGD的知识蒸馏
YOLOv8 基于MGD的知识蒸馏 接着上一篇我们介绍了YOLOv8的剪枝方案和代码,本篇文章将剪枝后的模型作为学生模型,剪枝前的模型作为教师模型对剪枝模型进行蒸馏,从而进一步提到轻量模型的性能。 Channel-wise Distillation (CWD) 问题和方法 …...
全国消防知识竞赛活动方案哪家强
关键词:消防安全、预防火灾、消防意识、消防员、防火安全 适合行业:所有行业 推荐功能:答题、投票、H5 宣传角度 1.从日常生活场景出发,指导大家如何检查家庭中的火灾隐患。例如检查电线是否老化、插座是否过载、是否在楼梯间…...
JavaEE学习一条龙服务————概述
鉴于之前的笔记较乱,没有逻辑关系,,博主决定从JacaEE整个学习的阶段出发,整理一系列博客,供大家学习交流,提升自己。 此文章已绑定一篇我为大家梳理的JavaEE一条龙学习知识点的文档,大家可下载…...
分支预测器BPU
分支预测器BPU 0 Intro0.1 CPU执行过程0.2 分支预测0.2.1 TAGE预测器0.2.2 跳转地址 分支预测器BPU是深入研究一个高性能处理器的一个很好的开始项目; 0 Intro 条件分支是指后续具有两路可执行的分支。可以分为跳转分支(taken branch)和不跳转分支(not-taken branc…...
Go 系列教程 —— 数组和切片
数组 数组是同一类型元素的集合。例如,整数集合 5,8,9,79,76 形成一个数组。Go 语言中不允许混合不同类型的元素,例如包含字符串和整数的数组。(译者注:当然,如果是 interface{} 类型数组,可以包含任意类型…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南
点一下关注吧!!!非常感谢!!持续更新!!! 🚀 AI篇持续更新中!(长期更新) 目前2025年06月05日更新到: AI炼丹日志-28 - Aud…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
基于江科大stm32屏幕驱动,实现OLED多级菜单(动画效果),结构体链表实现(独创源码)
引言 在嵌入式系统中,用户界面的设计往往直接影响到用户体验。本文将以STM32微控制器和OLED显示屏为例,介绍如何实现一个多级菜单系统。该系统支持用户通过按键导航菜单,执行相应操作,并提供平滑的滚动动画效果。 本文设计了一个…...
