【设计模式】创建型设计模式

文章目录

    • 1. 基础
      • ①如何学习设计模式
      • ② 类模型
      • ③ 类关系
    • 2. 设计原则
    • 3. 模板方法
      • ① 定义
      • ②背景
      • ③ 要点
      • ④ 本质
      • ⑤ 结构图
      • ⑥ 样例代码
    • 4. 观察者模式
      • ① 定义
      • ②背景
      • ③ 要点
      • ④ 本质
      • ⑤ 结构图
      • ⑥ 样例代码
    • 5. 策略模式
      • ① 定义
      • ②背景
      • ③ 要点
      • ④ 本质
      • ⑤ 结构图
      • ⑥ 样例代码

1. 基础

①如何学习设计模式

  • 找稳定点和变化点,把变化点隔离出来(解耦合)
  • 先满足设计原则,慢慢迭代出设计模式(抽象思维、分治思维)

② 类模型

在这里插入图片描述

③ 类关系

在这里插入图片描述

  • Stranger可以访问TonyFather中的public成员变量
  • TonyFather可以访问TonyFather中的public、protected成员变量
  • Beauty可以访问TonyFather中的public、protected以及private成员变量,但是TonyFather是无法访问Beauty中的protected和private成员变量的,因为友元是单向的
  • TonyMother与访问TonyFather可以互相访问对方的所有成员变量,因为两者都声明对方为友元

2. 设计原则

  • 开放封闭原则(Open Closed Principle,OCP):对扩展(组合和继承)开放,对修改关闭
  • 单一职责原则(Single Responsibility Principle,SRP):一个类或模块只负责一个功能,即一个类应该仅有一个引起它变化的原因
  • 里氏替换原则(Liskov Substitution Principle,LSP):子类可以替换父类,并且保持程序的正确性
  • 接口隔离原则(Interface Segregation Principle,ISP):接口应该尽量小而专一,不应该强迫客户依赖于它们不用的方法,避免臃肿和多余;一般用于处理一个类拥有比较多的接口,而这些接口涉及到很多职责
  • 面向接口原则(Interface Oriented Principle,IOP):不将变量类型声明为某个特定的具体类,而是声明为某个接口;客户程序无需获知对象的具体类型,只需要知道对象所具有的接口;减少系统中各个部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案
  • 依赖倒置原则(Dependence Inversion Principle,DIP):高层模块不应该依赖低层模块,二者都应该依赖抽象;抽象不应该依赖具体实现,具体实现应该依赖于抽象
  • 合成复用原则(Composite Reuse Principle,CRP):即组合优于继承原则,优先使用组合或聚合而不是继承来实现复用;继承耦合度高,组合耦合度低
  • 封装变化点原则(Package Change Point Principle,PCPP):将稳定点和变化点分离,扩展修改变化点;让稳定点和变化点实现层次分离
  • 迪米特法则(Law of Demeter,LoD):一个对象应该尽量少地了解其他对象

前四个设计原则最为重要

3. 模板方法

① 定义

定义一个操作中的算法骨架,而将一些步骤延迟到子类中

Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤

②背景

某一个表演有一套特定的展示流程,但是其中有若干个表演子流程可创新替换,宜昌市迭代更新表演流程

③ 要点

  • 最常用的设计模式,子类可以复写父类子流程,使弗雷德骨架流程丰富
  • 反向控制流程的典型应用
  • 父类protected保护子类需要复写的子流程,这样子类的子流程只能父类来调用

④ 本质

通过固定算法骨架来约束子类的行为

⑤ 结构图

在这里插入图片描述

⑥ 样例代码

#include <iostream>

using namespace std;

class Perform {
public:
    void show() {
        if (show0())
            playGame();
        show1();
        show2();
        show3();
    }

private:
    void playGame() {
        cout << "show0 end, have a small game" << endl;
    }

protected:
    virtual bool show0() {
        cout << "show0" << endl;
        return true;
    }
    virtual void show1() {

    }
    virtual void show2() {
        cout << "show2" << endl;
    }
    virtual void show3() {

    }
};

class PerformEx1 : public Perform {
protected:
    virtual bool show0() {
        cout << "ex1 show0" << endl;
        return true;
    }
    virtual void show2() {
        cout << "ex1 show2" << endl;
    }
};

class PerformEx2 : public Perform {
protected:
    virtual void show1() {
        cout << "ex2 show1" << endl;
    }
    virtual void show2() {
        cout << "ex2 show2" << endl;
    }
};

class PerformEx3 : public Perform {
protected:
    virtual void show1() {
        cout << "ex3 show1" << endl;
    }
    virtual void show2() {
        cout << "ex3 show2" << endl;
    }
    virtual void show3() {
        cout << "ex3 show3" << endl;
    }
};

int main()
{
    Perform *p1 = new PerformEx1();
    p1->show();
    cout << "====================" << endl;

    Perform *p2 = new PerformEx2();
    p2->show();
    cout << "====================" << endl;

    Perform *p3 = new PerformEx3();
    p3->show();
    cout << "====================" << endl;

    return 0;
}

补充

  • protected修饰符修饰类的成员可以被同一个类中的其他成员函数访问,也可以被派生类中的成员函数访问,但不能被其他地方访问;protected修饰符适用于继承关系中,保护基类的成员不被外部修改,但允许派生类修改
  • virtual关键字的作用是用来定义虚函数,实现动态绑定。虚函数是指在基类中声明为virtual的成员函数,它可以在派生类中被重写;当通过基类类型的指针或引用调用虚函数时,会根据对象的实际类型调用相应的重写版本;virtual关键字也可以用于虚继承,避免多重继承时出现菱形继承问题
  • virtual function() = 0的作用是定义纯虚函数。纯虚函数是一种没有实现的虚函数,它只有声明,没有定义;纯虚函数的目的是让派生类去重写它,实现多态;如果一个类中有纯虚函数,那么这个类就是抽象类,不能被实例化

4. 观察者模式

① 定义

定义对象间的一种一对多(变化)的依赖关系,以便当一个对象(subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新

②背景

气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到不同的显示终端上

③ 要点

  • 观察者模式使得我们可以独立地改变目标与观察者,从而使二者之间的关系松耦合
  • 观察者自己决定是否订阅通知,目标对象并不关注谁订阅了
  • 观察者不要依赖通知顺序,目标对象也不知道通知顺序
  • 常用在基于事件的ui框架中,也是MVC的组成部分
  • 常用在分布式系统和actor框架中
  • zk、etcd、kafka、redis、分布式锁

④ 本质

触发联动

⑤ 结构图

在这里插入图片描述

⑥ 样例代码

#include <iostream>
#include <vector>

using namespace std;

class IDisplay
{
public:
    virtual void show(float temperature) = 0;
    virtual ~IDisplay() {}
};

class DisplayA : public IDisplay
{
public:
    virtual void show(float temperature);

private:
    void ownFunction(); // 可以在子类上继续添加自己需要的函数
};

class DisplayB : public IDisplay
{
public:
    virtual void show(float temperature);
};

class DisplayC : public IDisplay
{
public:
    virtual void show(float temperature);
};

class WeatherData
{

};

class DataCenter
{
public:
    bool attach(IDisplay *ob);
    bool detach(IDisplay *ob);
    void notify()
    {
        float temperature = CalcTemperature();
        for (auto iter = this->obs.begin(); iter != obs.end(); iter++)
            (*iter)->show(temperature);
    }
private:
    virtual WeatherData *GetWeatherData();
    virtual float CalcTemperature()
    {
        WeatherData *data = GetWeatherData();
        // ...
        float temperature;
        return temperature;
    }
    std::vector<IDisplay *> obs;
};

int main()
{
    DataCenter *center = new DataCenter;
    IDisplay *da = new DisplayA();
    IDisplay *db = new DisplayB();
    IDisplay *dc = new DisplayC();
    center->attach(da);
    center->attach(db);
    center->attach(dc);

    center->notify();

    center->detach(db);
    center->notify();

    return 0;
}

5. 策略模式

① 定义

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换,该模式使得算法可独立于使用它的客户程序而变化

②背景

某商场节假日有固定促销活动,为了加大促销力度,现提升国庆节促销活动规格

③ 要点

  • 策略模式提供了一系列可重用的算法,从而可以使得类型在运⾏时方便地根据需要在各个算法之间进行切换
  • 策略模式消除了条件判断语句,也就是在解耦合

④ 本质

分离算法,选择实现

⑤ 结构图

在这里插入图片描述

⑥ 样例代码

#include <iostream>

using namespace std;

class Context
{
    // 环境类
};

class ProStrategy
{
    // 抽象的策略类
public:
    // 算法接口
    virtual double CalcPro(const Context &ctx) = 0;
    virtual ~ProStrategy();
};

// 派生出的具体策略类
class VAC_Spring : public ProStrategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

class VAC_Labor : public ProStrategy {
public:
    virtual double CalcPro(const Context &ctx){}
};
class VAC_Labor1  : public VAC_Labor {
public:
    virtual double CalcPro(const Context &ctx){}
};

class VAC_National : public ProStrategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

class VAC_Christmas : public ProStrategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

class Promotion
{
public:
    Promotion(ProStrategy *s) : s(s){}
    ~Promotion(){}
    double CalcPromotion(const Context &ctx) {
        return s->CalcPro(ctx);
    }
private:
    ProStrategy *s;
};

int main()
{
    Context ctx;
    ProStrategy *s = new VAC_Labor1();
    Promotion *p = new Promotion(s);
    p->CalcPromotion(ctx);
    return 0;
}

补充:

  • 析构函数设为虚函数:是为了实现多态性,即当用父类指针删除子类对象时,能够正确地调用子类的析构函数,从而避免内存泄漏或其他错误;如果父类的析构函数不是虚函数,那么只会调用父类的析构函数,导致子类的资源没有被释放

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

三维电子沙盘数字沙盘开发教程第7课

三维电子沙盘数字沙盘大数据人工智能开发教程第7课设置system.ini 如下内容Server122.112.229.220userGisTestPasswordchinamtouch.com该数据库中只提供 成都市火车南站附近的数据请注意&#xff0c;104.0648,30.61658利用三方工具&#xff0c;如幻影粒子&#xff1a;或者flash…

python例程:《彩图版飞机大战》程序

目录开发环境要求运行方法《彩图版飞机大战》程序使用说明源码示例源码及说明文档下载路径开发环境要求 本系统的软件开发及运行环境具体如下。 操作系统&#xff1a;Windows 7、Windows 10。 Python版本&#xff1a;Python 3.7.1。 开发工具&#xff1a;PyCharm 2018。…

软件测试拿了几个20K offer,分享一波面经

1、你的测试职业发展是什么? 测试经验越多&#xff0c;测试能力越高。所以我的职业发展是需要时间积累的&#xff0c;一步步向着高级测试工程师奔去。而且我也有初步的职业规划&#xff0c;前3年积累测试经验&#xff0c;按如何做好测试工程师的要点去要求自己&#xff0c;不断…

算法基础---基础算法

文章目录 快速排序归并排序二分 整数二分浮点数二分高精度 高精度加法高精度减法高精度乘法高精度除法前缀和 一维前缀和二维前缀和差分 一维差分二维差分双指针位运算离散化区间合并一、快速排序 思想&#xff1a;1.首先确定一个分界点&#xff08;随机取任意一点为…

【云原生】k8s集群命令行工具kubectl基础操作命令实践详解

kubectl基础操作命令详解一、准备工作1.1、Replication Controller1.2、Deployment1.3、DaemonSet1.4、查看创建的svc和pod1.5、kubectl 命令自动补全设置二、kubectl语法三、基础操作命令3.1、api-resources3.2、api-versions3.3、create3.4、expose3.5、run3.6、set3.6.1、en…

filebrowser的权限实现RBAC效果

filebrowser安装和支持定制化&#xff0c;建议参考我这一篇文章filebrowser安装言归正传&#xff0c;目前发现客户需要有文件权限管理功能&#xff0c;我一开始也没仔细研究这块&#xff0c;我以为不支持呢&#xff0c;我今天就认真的了研究 下这个存储服务&#xff0c;其实是支…

前端网络安全

什么是同源策略同源指的是&#xff1a;协议、端口号、域名必须一致。他是浏览器的一个用于隔离潜在恶意文件的重要安全机制。限制了从同一个源加载的文档或脚本&#xff0c;与另一个源的资源进行交互。同源策略主要限制了三个方面&#xff1a;当前域下的js脚本不能够访问其他域…

jsoup 框架的使用指南

概述 参考&#xff1a; 官方文档jsoup的使用JSoup教程jsoup 在 GitHub 的开源代码 概念简介 jsoup 是一款基于 Java 的 HTML 解析器&#xff0c;它提供了一套非常省力的 API&#xff0c;不但能直接解析某个 URL 地址、HTML 文本内容&#xff0c;而且还能通过类似于 DOM、CS…

【Java进阶篇】——反射机制

一、反射的概念 1.1 反射出现的背景 Java程序中&#xff0c;所有对象都有两种类型&#xff1a;编译时类型和运行时类型&#xff0c;而很多时候对象的编译时类型和运行时类型不一致 Object obj new String("hello")、obj.getClass(); 如果某些变量或形参的声明类型…

1、Linux初级——linux命令

下载镜像&#xff1a;http://cn.ubuntu.com/dowload 一、基本命令 1、alias&#xff08;给命令取别名&#xff09; 例如&#xff1a;alias clls -la&#xff08;只是临时的&#xff09; 2、配置文件$ vim ~/.bashrc $ vim ~/.bashrc // 使用vim打开配置文件 (1)在配置文件…

初识STM32单片机

目录 一、单片机基本认知 二、STM系列单片机命名规则 三、标准库与HAL库区别 四、通用输入输出端口GPIO 五、推挽输出与开漏输出 六、复位和时钟控制&#xff08;RCC&#xff09; 七、时钟控制 八、中断和事件 九、定时器介绍 一、单片机基本认知 单片机和PC电脑相比…

搜索系统(二)

term weight 如何衡量一个词在一篇文档中的重要性 词频率&#xff08;tf&#xff09;&#xff1a;term在文档中出现了多少次&#xff0c;tf越大说明越重要 逆文档频率&#xff08;idf&#xff09;&#xff1a;有多少文档包含了这个term&#xff0c;idf越大表明越不重要 综合…

Unity --- 游戏案例 --- 英雄无敌与Ruby

1.如何在场景中标识出一个空游戏物体&#xff08;对象集群&#xff09; 1.选中该空游戏物体&#xff0c;然后在Inspector面板处的物体名旁边添加想要的颜色的图标即可&#xff0c;最终效果如下图 2.这个图标只在场景中能开到&#xff0c;在游戏画面中是看不到的&#xff0c;其存…

Vulnhub项目:Web Machine(N7)

靶机地址&#xff1a;Web Machine(N7)渗透过程&#xff1a;kali ip&#xff1a;192.168.56.104&#xff0c;靶机ip&#xff0c;使用arp-scan进行查看靶机地址&#xff1a;192.168.56.128收集靶机开放端口&#xff1a;nmap -sS -sV -T5 -A 192.168.56.128开放了80端口&#xff0…

索尼mxf变成rsv的修复方法

索尼的影视级摄像机一般是用MXF文件结构&#xff0c;在一些极端情况下(如断电)会生成RSV文件&#xff0c;遇到这种情况我们应该如何处理&#xff1f;下面来看看今天这个案例。故障文件:12.51G RSV文件故障现象:断电后仅生成了一个扩展名为rsv的文件&#xff0c;使用播放器可以播…

python+django+vue全家桶鲜花商城售卖系统

重点&#xff1a; &#xff08;1&#xff09; 网上花店网站中各模块功能之间的的串联。 &#xff08;2&#xff09; 网上花店网站前台与后台的连接与同步。 &#xff08;3&#xff09; 鲜花信息管理模块中鲜花的发布、更新与删除。 &#xff08;4&#xff09; 订单…

java多线程之线程的六种状态

线程的六种状态(1) NEW(初始状态)(2) TERMINATED(终止状态 / 死亡状态)(3) RUNNABLE(运行时状态)(4) TIMED_WAITING(超时等待状态)(5) WAITING(等待状态)(6) BLOCK(阻塞状态)sleep和wait的区别:操作系统里的线程自身是有一个状态的,但是java Thread 是对系统线程的封装,把这里的…

基于C++的AI五子棋游戏项目开发教程

项目资源下载 基于C的AI五子棋游戏项目源码压缩包下载地址基于C的AI五子棋游戏项目源码Github下载地址基于C的AI五子棋游戏项目所需素材基于C的AI五子棋游戏项目所需要的EasyX 项目简介 本项目基于C开发&#xff0c;整体来说比较简单&#xff0c;实现了人与AI之间的五子棋对弈…

Java实习生------Redis常见面试题汇总(AOF持久化、RDB快照、分布式锁、缓存一致性)⭐⭐⭐

“年轻人&#xff0c;就要勇敢追梦”&#x1f339; 参考资料&#xff1a;图解redis 目录 谈谈你对AOF持久化的理解&#xff1f; redis的三种写回策略是什么&#xff1f; 谈谈你对AOF重写机制的理解&#xff1f;AOF重写机制的具体过程&#xff1f; 谈谈你对RDB快照的理解&a…

面试官:说一下MySQL中的锁机制吧

5. 1MySQL有哪些锁&#xff1f; 为保证数据的一致性&#xff0c;需要对并发操作进行控制&#xff0c;因此产生了锁。同时锁机制也为实现MySQL的各个隔离级别提供了保证。 锁冲突 也是影响数据库并发访问性能的一个重要因素。所以锁对数据库而言显得尤其重要&#xff0c;也更加…