创建型设计模式

1.设计模式是什么?

设计模式是指在软件开发过程中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案。

软件设计过程中,解决问题的固定套路。

慎用设计模式。

2.设计模式是怎么来的?

满足设计原则后,慢慢迭代出来的。

3.设计模式解决了什么问题?

前提:具体的需求,既有稳定点,也有变化点。

期望只修改少量的代码,就可以适应需求的变化。

比喻:整洁的房间,有一只好动的猫,如何保持房间的整洁。答:将猫关在笼子里。

4.设计模式基础。

面对对象的思想。三大特征:封装、继承、多态。

封装:隐藏实现细节,实现模块化

继承:无需修改原有类的情况下,通过继承,实现对原有功能的拓展。

多态:静态多态,即函数重载;动态多态,指继承中虚函数重写。

设计原则:依赖倒置;开闭原则:对扩展开放对修改关闭;面向接口:针对封装和多态;封装变化点;单一职责;里氏替换;组合优于继承;最小知道原则。

5.如何学习设计模式?

明确目的:在现有设计模式的基础上,扩展代码;做功能抽象时,如何选择设计模式。

学习步骤:

该设计模式解决了什么问题:稳定点、变化点;该设计模式的结构是什么;符合哪些设计原则;如何在上面扩展代码;该设计模式有哪些典型应用场景:联系目前的工作场景,开源框架等。

模板方法:

定义一个操作中的算法的骨架 ,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

稳定点:算法的骨架;变化点:子流程需要变化。

代码结构:基类中有骨架流程接口;所有子流程对子类开放并且是虚函数;多态使用方式。

符合设计原则:单一职责;开闭原则;依赖倒置(子类扩展时,需要依赖基类的虚函数实现;使用者只依赖接口);封装变化点:protected;接口隔离;最小知道原则。

如何扩展:实现子类继承基类,复写子流程;通过多态调用方式使用。

示例代码:
#include <iostream>
using namespace std;

// 开闭
class ZooShow {
public:
    void Show() {
        // 如果子表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接进入下一个子表演流程
        if (Show0())
            PlayGame();
        Show1();
        Show2();
        Show3();
    }

private:
    void PlayGame() {
        cout << "after Show0, then play game" << endl;
    }

protected:
    bool expired;
    // 对其他用户关闭,但是子类开放的
protected:
    virtual bool Show0() {
        cout << "show0" << endl;
        if (!expired) {
            return true;
        }
        return false;
    }
    virtual void Show2() {
        cout << "show2" << endl;
    }
    virtual void Show1() {

    }
    virtual void Show3() {

    }
};

// 框架
// 模板方法模式
class ZooShowEx10 : public ZooShow {
protected:
    virtual bool Show0() {
        if (!expired) {
            return true;
        }
        return false;
    }
};

class ZooShowEx1 : public ZooShow {
protected:
    virtual bool Show0() {
        cout << "ZooShowEx1 show0" << endl;
        if (!expired) { // 里氏替换
            return true;
        }
        return false;
    }
    virtual void Show2() {
        cout << "show3" << endl;
    }
};

class ZooShowEx2 : public ZooShow {
protected:
    virtual void Show1() {
        cout << "show1" << endl;
    }
    virtual void Show2() {
        cout << "show3" << endl;
    }
};

class ZooShowEx3 : public ZooShow {
protected:
    virtual void Show1() {
        cout << "show1" << endl;
    }
    virtual void Show3() {
        cout << "show3" << endl;
    }
    virtual void Show4() {
        //
    }
};
/*
*/
int main() {
    ZooShow* zs = new ZooShowEx10; // 晚绑定还是早绑定
    // ZooShow *zs1 = new ZooShowEx1;
    // ZooShow *zs2 = new ZooShowEx2;
    zs->Show();
    return 0;
}

运行结果:

观察者模式:

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

稳定点:"一"对“多”的依赖关系,“一”变化“多”跟着变化;变化点:“多”增加,“多”减少。

符合设计原则:面向接口编程、接口隔离(类与类依赖在一个接口)、封装变化点(attach,detach)。

如何扩展:继承实现接口,调用attach,调用detach

示例代码:

#include <list>
#include <algorithm>
#include <iostream>

using namespace std;
//
class IDisplay {
public:
    virtual void Show(float temperature) = 0;
    virtual ~IDisplay() {}
};

class DisplayA : public IDisplay {
public:
    virtual void Show(float temperature) {
        cout << "DisplayA Show" << endl;
    }
private:
    void jianyi();
};

class DisplayB : public IDisplay {
public:
    virtual void Show(float temperature) {
        cout << "DisplayB Show" << endl;
    }
};

class DisplayC : public IDisplay {
public:
    virtual void Show(float temperature) {
        cout << "DisplayC Show" << endl;
    }
};

class DisplayD : public IDisplay {
public:
    virtual void Show(float temperature) {
        cout << "DisplayD Show" << endl;
    }
};

class WeatherData {
};

// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
class DataCenter {
public:
    void Attach(IDisplay* ob) {
        obs.push_back(ob);
    }
    void Detach(IDisplay* ob) {
        //
    }
    void Notify() {
        float temper = CalcTemperature();
        for (auto iter : obs) {
            iter->Show(temper);
        }
    }

    // 接口隔离
private:
    WeatherData* GetWeatherData() { 
        WeatherData* wealthData = new WeatherData;
        return wealthData;
    }

    float CalcTemperature() {
        WeatherData* data = GetWeatherData();
        // ...
        float temper = 0;
        return temper;
    }
    std::list<IDisplay*> obs;
};

int main() {
    // 单例模式
    DataCenter* center = new DataCenter;
    // ... 某个模块
    IDisplay* da = new DisplayA();
    center->Attach(da);

    // ...
    IDisplay* db = new DisplayB();
    center->Attach(db);

    IDisplay* dc = new DisplayC();
    center->Attach(dc);

    center->Notify();

    //-----
    center->Detach(db);
    center->Notify();


    //....
    //center->Attach(dd);

    center->Notify();
    return 0;
}

 运算结果:

策略模式:

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

解决了什么问题:稳定点:客户程序与算法的调用关系;变化点:算法变化(新加算法、算法内容变化)。

设计原则:接口隔离(依赖注入、解决通过一个接口解决两个类的依赖);面向接口编程

示例代码:

class Context {

};

// 稳定点:抽象去解决它
// 变化点:扩展(继承和组合)去解决它
class ProStategy {
public:
    virtual double CalcPro(const Context& ctx) = 0;
    virtual ~ProStategy();
};
// cpp
class VAC_Spring : public ProStategy {
public:
    virtual double CalcPro(const Context& ctx) {}
};
// cpp
class VAC_QiXi : public ProStategy {
public:
    virtual double CalcPro(const Context& ctx) {}
};
class VAC_QiXi1 : public VAC_QiXi {
public:
    virtual double CalcPro(const Context& ctx) {}
};
// cpp
class VAC_Wuyi : public ProStategy {
public:
    virtual double CalcPro(const Context& ctx) {}
};
// cpp
class VAC_GuoQing : public ProStategy {
public:
    virtual double CalcPro(const Context& ctx) {}
};

class VAC_Shengdan : public ProStategy {
public:
    virtual double CalcPro(const Context& ctx) {}
};

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

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

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

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

相关文章

数据库实战(一)(关系数据库设计)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;数据库 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 前言 练习题 题型一&#xff1a;判断关系…

“首秀”欧洲杯,海信冰箱欧洲市占率居国产品牌首位

随着欧洲杯的火热开赛&#xff0c;挑灯夜战、观看球赛的时刻已经来临。此时&#xff0c;你需要何物相伴&#xff1f;是打开冰箱&#xff0c;取出真空腌制的食材&#xff0c;亲手烹饪一场观赛盛宴&#xff1f;还是取出极致保鲜的荔枝、樱桃&#xff0c;一边观赛一边品味&#xf…

如何避免接口重复请求(axios推荐使用AbortController)

前言&#xff1a; 我们日常开发中&#xff0c;经常会遇到点击一个按钮或者进行搜索时&#xff0c;请求接口的需求。 如果我们不做优化&#xff0c;连续点击按钮或者进行搜索&#xff0c;接口会重复请求。 以axios为例&#xff0c;我们一般以以下几种方法为主&#xff1a; 1…

【文献阅读】Partially Adaptive Array Techniques

Abstract 文章研究了在多窄带干扰环境下&#xff0c;辅助阵元的选择&#xff0c;为部分自适应天线阵&#xff0c;以达到性能优化的目的。推导了双干扰问题的显式解。这个案例足以说明多个干扰的相互作用&#xff0c;同时也为更复杂的问题提供了一定程度的理解。本文还提出并讨…

如何实现ElementUI动态表头?

可能看到这个标题,有些小伙伴会有些疑惑,动态表头是个什么东西,怎么没听说过? 其实动态表头在企业的项目中用途还是非常广泛的,比如erp系统什么的 那么动态表头是什么呢?说简单点就是让ElementUI的Table表格可以实现自定义表头展示+表头拖拽排序的一个功能 这个东西我…

本地运行大语言模型(LLMs)

用例 像PrivateGPT、llama.cpp、Ollama、GPT4All、llamafile 等项目的流行度凸显了本地&#xff08;在您自己的设备上&#xff09;运行大型语言模型&#xff08;LLMs&#xff09;的需求。 这至少有两个重要的好处&#xff1a; 1.隐私&#xff1a;您的数据不会发送给第三方&a…

Mars3d实现汽车尾气粒子效果从汽车屁股开始发射效果

本身的汽车尾气粒子效果&#xff1a;在汽车模型的中间发射的↓↓↓↓↓↓↓↓↓↓↓ Mars3d实例中是使用transY偏移值实现汽车尾气粒子效果从汽车屁股开始发射效果&#xff1a; // 动态运行车辆的尾气粒子效果 function addDemoGraphic4(graphicLayer) {const fixedRoute new…

【odoo】如何开启开发者模式,开启有什么作用?

概要 在 Odoo 中&#xff0c;开发者模式&#xff08;Developer Mode&#xff09;是一种专门为开发和调试提供的模式。启用开发者模式可以让开发人员访问到更多的功能和信息&#xff0c;从而更方便地进行模块开发、调试和测试。 启用方式&#xff08;主要两种&#xff09; 1.设…

windows实现python串口编程

一、windows安装python Welcome to Python.org 根据windows是64位找到对应的版本下载 下载完后直接安装即可&#xff01; 打开cmd查看python版本 $ python --version #查看版本 二、串口编程 1、安装pyserial库 pyserial是Python中的一个库,用于处理串口通信。 cmd…

DDP算法之线性化和二次近似(Linearization and Quadratic Approximation)

DDP算法线性化和二次近似 在DDP算法中,第三步是线性化系统动力学方程和二次近似代价函数。这一步是关键,它使得DDP能够递归地处理非线性最优控制问题。通过线性化和二次近似,我们将复杂的非线性问题转换为一系列简单的线性二次问题,逐步逼近最优解。通过这些线性化和二次近…

如何解决 NumPy 无法计算其中一个 5 元素列表的标准差的问题

问题背景 在使用 NumPy 计算统计结果时发现&#xff0c;NumPy 能够接受原始数据列表来计算标准差&#xff0c;却无法接受经过计算后的结果列表。尝试将 std(f10) 替换为 std(solf10)&#xff0c;但引发了错误&#xff1a;AttributeError: Float object has no attribute sqrt。…

vue页面前端初始化表格数据时报错TypeError: data.reduce is not a function

这是初始化表格数据时报的错 。 [Vue warn]: Invalid prop: type check failed for prop "data". Expected Array, got Object found in---> <ElTable> at packages/table/src/table.vue<List> at src/views/org/List.vue<Catalogue> at src/v…

Java毕业设计 基于SSM助学贷款管理系统

Java毕业设计 基于SSM助学贷款管理系统 SSM 助学贷款管理系统 功能介绍 学生&#xff1a;登录 修改密码 学生信息 贷款项目信息 申请贷款 留言信息 公告 学校负责人&#xff1a;登录 修改密码 学生管理 学校负责人信息 贷款项目 贷款申请审批 留言信息 公告 银行负责人&…

媒体邀约人物访谈,如何有效提升品牌影响力?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 品牌选择媒体邀约人物专访的形式来背书&#xff0c;可以带来以下好处&#xff1a; 增强品牌权威性&#xff1a;通过知名媒体的专访&#xff0c;品牌可以借助媒体的权威性来提升自身的信誉…

“运动过量”?想多了,普通骑友没那能力和意志力,好好骑车吧

最近听到“运动过量”这个词挺多的&#xff0c;身为骑行爱好者的校长&#xff0c;感觉又好笑又无奈&#xff0c;所以想写点东西&#xff0c;这篇文通过分析普通骑友的运动习惯、能力和意志力&#xff0c;探讨了“运动过量”这一概念在骑行领域中的适用性。文章指出&#xff0c;…

vue2实现一个简易实用的日历(可特殊标记多个日期)

效果如下&#xff1a; <template><div class"calendar"><div class"header"><button click"previousMonth"><</button><h2>{{ currentYear }}-{{ currentMonth }} </h2><button click"nex…

会员收银系统源码

会员营销是一种基于会员管理的营销方法&#xff0c;通过提供会员专属的优惠、服务和体验&#xff0c;吸引和保留客户&#xff0c;促进客户的持续消费。与直接打折相比&#xff0c;会员营销具有以下优势&#xff1a; 1.增强客户忠诚度 会员营销可以通过提供个性化的服务和专属…

【面试八股文】谈一谈你对TCP和UDP的区别是怎么理解的?

文章目录 一、TCP和UDP的区别,使用打电话和写信来类比1.1 TCP就像打电话1.2 UDP就像写信1.3 总结二、专业的讲解`TCP`和`UDP`的区别2.1 TCP和UDP的概念2.2 是否面向连接2.3 从连接对象个数来看2.3.1 UDP:UDP支持一对一、一对多、多对一、多对多的通信。2.3.3 TCP:TCP是一对一…

快速了解接口测试

1、定义 什么是接口测试&#xff1f; 接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 接口测…

第一次创建next.js项目

当前环境和版本&#xff1a; 创建命令&#xff1a; npx create-next-applatest test-nextjs 下载过程&#xff1a; 虽然下载过程有warning&#xff0c;但是还是下载成功了 node.js稳定版本号&#xff1a;http://t.csdnimg.cn/WokUx 因为它前面warn说要> 18.17.0 所以下载了…