设计模式 - 结构型

news2024/10/12 8:14:23

结构型

适配器模式,代理模式,桥接模式,装饰器模式,外观模式,组合模式,享元模式,

单一职责避免子类爆炸
Bridge 模式对象的实现
Decorator 模式对对象的职责,不生成子类
接口隔离
Adapter 模式针对对象的接口
Facade 模式对一个子系统的接口
Proxy 模式如何访问一个对象;该对象的位置
数据结构
Composite 模式一个对象的结构和组成
对象性能
Flyweight 模式对象的存储开销

单一职责(避免子类爆炸)

subclass explode

Bridge 桥接模式
概念

桥接模式和装饰器模式一样,解决因为没有遵循单一职责原则而导致的子类数量爆炸。

  • 装饰器模式

    • 组合且继承

      子类可能会调用其他子类的实现。

  • 桥接模式

    • 组合而不继承。

      实现类 不会调用其他子类的实现

    • 实现类对应拆分前的子类,实际上由于没有继承,所以这里叫实现类更好。

  • 核心思想都是一样的,组合优于继承,单一职责。

具体来说:1+n+n*m 个子类,变为 1 纯虚 (+ 1通用实现)+ n iml实现类 + m个应用场景

  • 1 纯虚:接口
  • n 平台实现Imp
  • m 业务抽象(特定平台不同版本) (Imp平台实现作为参数 拼装)

业务抽象不需要继承接口或者平台实现,持有的基类的指针,运行时会指向iml平台实现(实现类)。

  • 桥接模式实现了抽象化与实现化的脱耦。他们两个互相独立,不会影响到对方。
  • 对于两个独立变化的维度,使用桥接模式再适合不过了。
  • 分离抽象接口及其实现部分。提高了比继承更好的解决方案
code

bridge.h

#include <cstdio>
#include <iostream>

class AbstractionImp {
public:
    virtual void Operation_RunPythonInTerminal() = 0;
};

// ConcreteAbstractionImp
class ConcreteAbstractionImp_Python2 : public AbstractionImp {
public:
    void Operation_RunPythonInTerminal() {
        printf("start python2 \n");
    }
};

class ConcreteAbstractionImp_Python3 : public AbstractionImp {
public:
    void Operation_RunPythonInTerminal() {
        printf("start python3 \n");
    }
};

bridge.cpp

#include "bridge_Imp.h"
// class AbstractionImp;

class Abstraction {
public:
    AbstractionImp* mImp = nullptr;
    virtual void Operation_RunPythonInTerminal() = 0;
};

class RefinedAbstraction_Windows : public Abstraction{
public:
    void Operation_RunPythonInTerminal() {
        printf("windows start WSL\n");
        if (mImp)
            mImp->Operation_RunPythonInTerminal();
    }
};

class RefinedAbstraction_Linux : public Abstraction{
public:
    void Operation_RunPythonInTerminal() {
        printf("linux start cmd\n");
        if (mImp)
            mImp->Operation_RunPythonInTerminal();
    }
};


int main() {
    Abstraction* mOS = new RefinedAbstraction_Windows;
    AbstractionImp* mPython = new ConcreteAbstractionImp_Python3;
    mOS->mImp = mPython;
    mOS->Operation_RunPythonInTerminal();
    free(mPython);
    mPython = new ConcreteAbstractionImp_Python2;
    mOS->mImp = mPython;
    mOS->Operation_RunPythonInTerminal();
    free(mPython);
    free(mOS);
    return 0;
}
Decorator 装饰器
概念

单一职责,避免了子类的无限制膨胀,消除重复代码,兼具开闭选择。

  • 特征

    • 子类继承基类

      多继承,多子类衍生 时的一个解决方法

    • 子类持有基类的指针。

      根据里氏替换,可以调用基类的同名方法,并在前后加上子类的操作。组合优于继承。

  • 应用于 主体类多个方向上的扩展功能

    • 主体操作和扩展操作,应该分开分支继承。

    • 扩展操作通过持有的主体操作的指针,造成附加动作之后 调用主体操作。

code
#include <cstdio>
#include <iostream>
#include <iostream>
#include <string>

class DecoratorBase {
public:
    DecoratorBase* mImp = nullptr;
    virtual void Operation() = 0;
};

class ImpParty : public DecoratorBase {
public:
    std::string bro = "";
    ImpParty(std::string bro) {
        this->bro = bro;
    }
    void setBro(std::string name) {
        this->bro = name;
    }
    void Operation() {
        printf("Party start, hi %s\n", bro.c_str());
        if (mImp) {
            printf("lets drink!\n");
            mImp->Operation();
        }
    }
};

class ImpSoftDrink : public DecoratorBase {
public:
    std::string softdrink = "";
    ImpSoftDrink(std::string softdrink) {
        this->softdrink = softdrink;
    }
    void Operation() {
        printf("lets drink %s", softdrink.c_str());
    }
};

int main() {
    ImpParty* mParty = new ImpParty("John");
    ImpSoftDrink* mDrink = new ImpSoftDrink("cola");
    mParty->mImp = mDrink;
    mParty->Operation();
    delete mDrink;
    delete mParty;
    return 0;
}

数据结构

composite 组合模式
概念

将对象组合成树状结构,树形结构不暴露给外界。

Compoment

树节点 composite 子类

  • 持有 一个子类的链表

  • add remove方法修改 其中的子类的链表

  • process方法,执行子类链表中所有子类的process函数。直到叶子节点

叶子节点 leaf 没有链表,process函数执行功能。

接口隔离

其它人的代码
Adoptor 适配器模式
概念

为了完成某项工作购买了一个第三方的库来加快开发。这就带来了一个问题:我们在应用程序中已经设计好了接口,与这个第三方提供的接口不一致,为了使得这些接口不兼容的类(不能在一起工作)可以在一起工作了,Adapter 模式提供了将一个类(第三方库)的接口转化希望的接口。

Itarget新实现的接口。adapter新实现。adaptee被适配的旧类

适配器模式分为类模式和对象模式。

  • 常用做法。对象模式:对象适配器 adapter,采用组合原有接口类的方式

    • 持有adaptee,组合用于实现。

    • public继承Itarget 接口。

  • 不常用做法。类模式:类适配器 adapter,采用继承原有接口类的方式

    • protect继承adaptee,用于实现。

    • public继承Itarget接口。(不灵活 继承的方案不灵活 类的多继承在cpp之外的语言压根就不支持)

code 继承
#include <cstdio>
class Target_rob {
public:
    virtual int giveMeYrMoney() = 0;
};

class Adaptee_robInFrance {
public:
    int doRob() {
        printf("Levez les mains, donnez moi votre argent!\n");
        return 1000;
    }
};

class Adaptor_rob : public Target_rob, Adaptee_robInFrance {
public:
    int giveMeYrMoney() {
        return doRob();
    }
};

int main() {
    Target_rob* mClinet = dynamic_cast<Target_rob*>(new Adaptor_rob());
    int money = mClinet->giveMeYrMoney();
    printf("we got %d RMB!", money);
}

code 组合
#include <cstdio>
#include <cstdlib>
class Adaptee_rob {
public:
    virtual int doRob() = 0;
};
class Adaptee_robInFrance : public Adaptee_rob {
public:
    int doRob() {
        printf("Levez les mains, donnez moi votre argent!\n");
        return 1000;
    }
};

class Target_rob {
public:
    Adaptee_rob* mAdaptee = nullptr;
    virtual int giveMeYrMoney() = 0;
};

class Adaptor_rob : public Target_rob {
public:

    int giveMeYrMoney() {
        int money = 0;
        if (mAdaptee) {
            money = mAdaptee->doRob();
        } else {
            printf("we got nothing \n");
        }
        return money;
    }
};

int main() {
    Target_rob* mClinet = dynamic_cast<Target_rob*>(new Adaptor_rob());
    Adaptee_rob* mRobber = dynamic_cast<Adaptee_rob*>(new Adaptee_robInFrance());
    mClinet->mAdaptee = mRobber;
    int money = mClinet->giveMeYrMoney();
    printf("we got %d RMB!", money);
    return 0;
}
facade 门面模式

facad 门面模式 解欧系统见的交互

框架层面,没有具体的实例代码。对内 高内聚 对外应该松耦合。

封装内部可能高度复杂 高度耦合的盒子。例如安卓的vendor hal。数据访问相关sql等等。

Proxy 代理模式

在不失去透明操作对象的同时,控制管理这些对象内部特有的复杂性

对其他对象特供一种代理,以控制 (隔离 使用接口)对这个接口的访问。

  • 对象创建开销大
  • 某些操作需要安全控制
  • 需要进程外的访问(分布式等)

对象性能

Flyweight 享元模式

内存池,每个字的字体,单例模式从容器中取出。

实现 右值引用 复制,clone原型模式

––– 接口隔离 –––

  • List item

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

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

相关文章

openpdf

1、简介 2、示例 2.1 引入依赖 <dependency><groupId>com.github.librepdf</groupId><artifactId>openpdf</artifactId><version>1.3.34</version></dependency><dependency><groupId>com.github.librepdf</…

正点原子STM32F407ZG 开发板简介

1. STM32F407ZG 学习资料 1&#xff09;ST 官方的学习资料 ST 官方资料有两个网址&#xff1a; www.stmcu.org.cn 和 www.st.com 。 www.stmcu.org.cn 是 ST 中文社区&#xff0c;里面的资料全部由 ST 中国区的人负责更新和整理&#xff0c;包含了所有 ST 公司的 …

计算机的错误计算(一百二十)

摘要 探讨在许多应用中出现的函数 的计算精度问题。 例1. 考虑在许多应用中出现的函数 计算 不妨在Python下计算&#xff1a; 若用下列Rust代码在线计算&#xff1a; fn f(x: f64) -> f64 {(x.exp() - 1.0) / x }fn main() {let result f(0.9e-13);println!("…

微知-Bluefield DPU命名规则各字段作用?BF2 BF3全系列命名大全

文章目录 背景字段命名C是bmc的意思NOT的N是是否加密S表示不加密但是secureboot enable倒数第四个都是E倒数第五个是速率 V和H是200GM表示E serials&#xff0c;H表示P serials&#xff08;区别参考兄弟篇&#xff1a;[more](https://blog.csdn.net/essencelite/article/detail…

【通信协议讲解】单片机基础重点通信协议解析与总结(IIC,CAN,MODBUS...)

目录 一.IIC总线 基础特性&#xff1a; 配置特性&#xff1a; 时序特性&#xff1a; 二.SPI总线 基础特性&#xff1a; 配置特性&#xff1a; 时序特性&#xff1a; 三.串口通信 基础特性&#xff1a; 配置特性&#xff1a; 时序特性&#xff1a; 四.CAN总线 基础特性…

vue后台管理系统从0到1(5)

文章目录 vue后台管理系统从0到1&#xff08;5&#xff09;完善侧边栏修改bug渲染header导航栏 vue后台管理系统从0到1&#xff08;5&#xff09; 接上一期&#xff0c;我们需要完善我们的侧边狼 完善侧边栏 我们在 element 组件中可以看见&#xff0c;这一个侧边栏是符合我们…

I/O进程(Day26)

一、学习内容 I/O进程 标准IO 概念 针对文件的读写操作 文件IO最终达成的目的&#xff1a;将一个临时存在于内存中的数据&#xff0c;永久性的存放于磁盘当中 操作 文件IO的操作&#xff0c;需要这样的2个指针 一个指针&#xff1a;指向源数据&#xff0c;提供读取操作的指针 …

复杂系统学习

一、复杂网络分析在复杂性研究中的地位 1.复杂系统 系统中存在的复杂度从两个维度来看 ①系统自由度&#xff08;系统组成成分的数目&#xff09; ②相互作用&#xff08;线性到非线性的转换&#xff09; 复杂网络是复杂系统的骨架 复杂系统可以抽象成一个网络&#xff0…

大数据新视界 --大数据大厂之 Dremio:改变大数据查询方式的创新引擎

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

【JVM】如何判断对象是否可以被回收

引用计数法&#xff1a; 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 优点&#xff1a;实现简单&#xff0c;判…

Visual Studio--VS安装配置使用教程

Visual Studio Visual Studio 是一款功能强大的开发人员工具&#xff0c;可用于在一个位置完成整个开发周期。 它是一种全面的集成开发环境 (IDE)。对新手特别友好&#xff0c;使用方便&#xff0c;不需要复杂的去配置环境。用它学习很方便。 Studio安装教程 Visual Studio官…

从这里看BD仓储如何改变物流效率?

BD仓储物流建设成为当代物流领域的核心要素&#xff0c;推动着整个行业朝向高效性与智能化水平不断提升。在BD仓储物流的创新浪潮中&#xff0c;RFID技术犹如一颗耀眼的明珠&#xff0c;凭借其无可比拟的特性获得了业界的广泛推崇与广泛应用。该技术通过无线信号与电子标签的互…

Python剪辑视频

import os from moviepy.editor import VideoFileClipvideo_dir r"E:\学习\视频剪辑" s_video_file "1.mp4" d_video_file "剪辑片段1.mp4" s_video_path os.path.join(video_dir, s_video_file) # 原视频文件路径 d_video_path os.path…

FDTD Solutions(时域有限差分)仿真技术与应用

FDTD Solutions是一款非常好用的微纳光学设计工具。该软件提供了丰富的设计功能&#xff0c;支持CMOS图像传感器&#xff0c;OLED和液晶&#xff0c;表面计量&#xff0c;表面等离子体&#xff0c;石墨烯&#xff0c;太阳能电池&#xff0c;集成光子组件&#xff0c;超材料&…

排序|归并排序|递归|非递归|计数排序(C)

归并排序 如果数组的左半区间有序&#xff0c;右半区间有序&#xff0c;可以直接进行归并 基本思想 快排是一种前序&#xff0c;归并是后序 每次取小尾插 void _MergeSort(int* a, int* tmp, int begin, int end) {if (end < begin)return;int mid (end begin) / 2;/…

go开发环境设置-安装与交叉编译

1. 引言 Go语言&#xff0c;又称Golang&#xff0c;是Google开发的一门编程语言&#xff0c;以其高效、简洁和并发编程的优势受到广泛欢迎。作为一门静态类型、编译型语言&#xff0c;Go在构建网络服务器、微服务和命令行工具方面表现突出。 在开发过程中&#xff0c;开发者常…

PyCharm打开及配置现有工程(详细图解)

本文详细介绍了如何利用Pycharm打开一个现有的工程&#xff0c;其中包括编译器的配置。 PyCharm打开及配置现有工程 1、打开工程2、配置编译器 1、打开工程 双击PyCharm软件&#xff0c;点击左上角 文件 >> 打开(O)… 选中想要打开的项目之后点击“确定” 2、配置编译器…

STM32学习--3-5 光敏控制传感器控制蜂鸣器

接线图 Buzzer.c #include "stm32f10x.h" // Device header void Buzzer_Init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_O…

Microsoft Visual Studio安装gtest

1. 参考【Windows Visual Studio下安装和使用google test&#xff08;gtest&#xff09;】 https://blog.csdn.net/Bule_Zst/article/details/78420894 2. 编译gtest使用Win32模式。 3. 配置属性&#xff0c;C/C&#xff0c;常规&#xff0c;附加包含目录 …

【画质模组】古墓丽影mod,调色并修改光影,游戏画质大提升

大家好&#xff0c;今天小编我给大家继续引入一款游戏mod&#xff0c;这次这个模组主要是针对雷神之锤4进行修改&#xff0c;如果你觉得游戏本身光影有缺陷&#xff0c;觉得游戏色彩有点失真的话&#xff0c;或者说你想让雷神之锤4这款游戏增加对光线追踪的支持的话&#xff0c…