C++设计模式

Wesley13
• 阅读 615

参考:https://www.runoob.com/design-pattern/design-pattern-tutorial.html

参考:https://blog.csdn.net/liang19890820/article/details/66974516

设计模式就是指面向对象编程中面多众多的实践中而发展总结出来的很多精华的特定

的代码组织方式。使用这些方式可以使你更加科学合理、高效的管理和组织你的代码。

代码好比你的千军万马,设计模式好比你的指挥体系。

总原则:看看就好

6大原则(六脉神剑):看看就好

1、开闭原则(Open Close Principle)

开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。

2、里氏代换原则(Liskov Substitution Principle)

里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

3、依赖倒转原则(Dependence Inversion Principle)

这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

5、迪米特法则,又称最少知道原则(Demeter Principle)

最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

合成复用原则是指:尽量使用合成/聚合的方式,而不是使用继承。

总共氛围以下3大类:

1、Creational - 创建型模式

工厂模式(Factory Pattern)

// Factory.cpp : 定义控制台应用程序的入口点。
// 简单工厂模式
 
#include "stdafx.h"
#include<iostream>
 
using namespace std;
 
class Product
{
public:
    virtual void show() = 0;  
};
 
class Product_A : public Product
{
public:
    void show()
    {
        cout << "Product_A" << endl;
    }
};
 
class Product_B : public Product
{
public:
    void show()
    {
        cout << "Product_B" << endl;
    }
};
 
class Factory
{
public:
    Product* Create(int i)
    {
        switch (i)
        {
        case 1:
            return new Product_A;
            break;
        case 2:
            return new Product_B;
            break;
        default:
            break;
        }
    }
};
 
int main()
{
    Factory *factory = new Factory();
    factory->Create(1)->show();
    factory->Create(2)->show();
    system("pause");
    return 0;
}

//工厂模式
#include "stdafx.h"
#include<iostream>
 
using namespace std;
 
class Product
{
public:
    virtual void show() = 0;  
};
 
class Product_A : public Product
{
public:
    void show()
    {
        cout << "Product_A" << endl;
    }
};
 
class Product_B : public Product
{
public:
    void show()
    {
        cout << "Product_B" << endl;
    }
};
 
class Factory
{
public:
    virtual Product* create() = 0;
};
 
class Factory_A : public Factory
{
public:
    Product* create()
    {
        return new Product_A;
    }
};
 
class Factory_B : public Factory
{
public:
    Product* create()
    {
        return new Product_B;
    }
};
 
int main()
{
    Factory_A* productA = new Factory_A();
    Factory_B* productB = new Factory_B();
 
    productA->create()->show();
    productB->create()->show();
    system("pause");
    return 0;
}

抽象工厂模式(Abstract Factory Pattern)

//抽象工厂模式
#include <iostream>
using namespace std;  
  
//定义抽象类  
class product1  
{  
public:  
    virtual void show() = 0;  
};  
  
//定义具体类  
class product_A1 :public product1  
{  
public:  
    void show(){ cout << "product A1" << endl; }  
};  
  
class product_B1 :public product1  
{  
public:  
    void show(){ cout << "product B1" << endl; }  
};  
  
//定义抽象类  
class product2  
{  
public:  
    virtual void show() = 0;  
};  
  
//定义具体类  
class product_A2 :public product2  
{  
public:  
    void show(){ cout << "product A2" << endl; }  
};  
  
class product_B2 :public product2  
{  
public:  
    void show(){ cout << "product B2" << endl; }  
};  
  
  
class Factory
{  
public:  
    virtual product1 *creat1() = 0;  
    virtual product2 *creat2() = 0;  
};  
  
class Factory1 : public Factory 
{  
public:  
    product1 *creata(){ return new product_A1(); }  
    product2 *creatb(){ return new product_B1(); }  
};  
  
class Factory2 : public Factory  
{  
public:  
    product1 *creata(){ return new product_A2(); }  
    product2 *creatb(){ return new product_B2(); }  
};  
  
int main()  
{  
    Factory *factory1 = new Factory1();  
    factory1->creata()->show();  
    factory1->creatb()->show();  
  
    Factory *factory2 = new Factory2();  
    factory2->creata()->show();  
    factory2->creatb()->show();  
  
    return 0;  
}

单例模式(Singleton Pattern)

建造者模式(Builder Pattern)

原型模式(Prototype Pattern)

2、Structural - 结构型模式

适配器模式(Adapter Pattern)

桥接模式(Bridge Pattern)

过滤器模式(Filter、Criteria Pattern)

组合模式(Composite Pattern)

装饰器模式(Decorator Pattern)

外观模式(Facade Pattern)

享元模式(Flyweight Pattern)

代理模式(Proxy Pattern)

3、Behavioral - 行为型模式

责任链模式(Chain of Responsibility Pattern)

命令模式(Command Pattern)

解释器模式(Interpreter Pattern)

迭代器模式(Iterator Pattern)

中介者模式(Mediator Pattern)

备忘录模式(Memento Pattern)

观察者模式(Observer Pattern)

// subject.h
#ifndef SUBJECT_H
#define SUBJECT_H

class IObserver;

// 抽象主题
class ISubject
{
public:
    virtual void Attach(IObserver *) = 0;  // 注册观察者
    virtual void Detach(IObserver *) = 0;  // 注销观察者
    virtual void Notify() = 0;  // 通知观察者
};

#endif // SUBJECT_H

// concrete_subject.h
#ifndef CONCRETE_SUBJECT_H
#define CONCRETE_SUBJECT_H

#include "subject.h"
#include "observer.h"
#include <iostream>
#include <list>

using namespace std;

// 具体主题
class ConcreteSubject : public ISubject
{
public:
    ConcreteSubject() { m_fPrice = 10.0; }

    void SetPrice(float price) {
        m_fPrice = price;
    }

    void Attach(IObserver *observer) {
        m_observers.push_back(observer);
    }

    void Detach(IObserver *observer) {
        m_observers.remove(observer);
    }

    void Notify() {
        list<IObserver *>::iterator it = m_observers.begin();
        while (it != m_observers.end()) {
            (*it)->Update(m_fPrice);
            ++it;
        }
    }

private:
    list<IObserver *> m_observers;  // 观察者列表
    float m_fPrice;  // 价格
};

#endif // CONCRETE_SUBJECT_H

// observer.h
#ifndef OBSERVER_H
#define OBSERVER_H

// 抽象观察者
class IObserver
{
public:
    virtual void Update(float price) = 0;  // 更新价格
};

#endif // OBSERVER_H

// concrete_observer.h
#ifndef CONCRETE_OBSERVER_H
#define CONCRETE_OBSERVER_H

#include "observer.h"
#include <iostream>
#include <string>

using namespace std;

// 具体观察者
class ConcreteObserver : public IObserver
{
public:
    ConcreteObserver(string name) { m_strName = name; }

    void Update(float price) {
        cout << m_strName << " - price: " << price << "\n";
    }

private:
     string m_strName;  // 名字
};

#endif // CONCRETE_OBSERVER_H

// main.cpp
#include "concrete_subject.h"
#include "concrete_observer.h"

#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p){delete(p); (p)=NULL;} }
#endif

int main()
{
    // 创建主题、观察者
    ConcreteSubject *pSubject = new ConcreteSubject();
    IObserver *pObserver1 = new ConcreteObserver("Jack Ma");
    IObserver *pObserver2 = new ConcreteObserver("Pony");

    // 注册观察者
    pSubject->Attach(pObserver1);
    pSubject->Attach(pObserver2);

    // 更改价格,并通知观察者
    pSubject->SetPrice(12.5);
    pSubject->Notify();

    // 注销观察者
    pSubject->Detach(pObserver2);
    // 再次更改状态,并通知观察者
    pSubject->SetPrice(15.0);
    pSubject->Notify();

    SAFE_DELETE(pObserver1);
    SAFE_DELETE(pObserver2);
    SAFE_DELETE(pSubject);

    getchar();

    return 0;
}

状态模式(State Pattern)

空对象模式(Null Object Pattern)

策略模式(Strategy Pattern)

模板模式(Template Pattern)

访问者模式(Visitor Pattern

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Stella981 Stella981
3年前
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解
Opencv中Mat矩阵相乘——点乘、dot、mul运算详解2016年09月02日00:00:36 \牧野(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fme.csdn.net%2Fdcrmg) 阅读数:59593
Stella981 Stella981
3年前
C# Aspose.Cells导出xlsx格式Excel,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
报错信息:最近打开下载的Excel,会报如下错误。(xls格式不受影响)!(https://oscimg.oschina.net/oscnet/2b6f0c8d7f97368d095d9f0c96bcb36d410.png)!(https://oscimg.oschina.net/oscnet/fe1a8000d00cec3c
Stella981 Stella981
3年前
Linux查看GPU信息和使用情况
1、Linux查看显卡信息:lspci|grepivga2、使用nvidiaGPU可以:lspci|grepinvidia!(https://oscimg.oschina.net/oscnet/36e7c7382fa9fe49068e7e5f8825bc67a17.png)前边的序号"00:0f.0"是显卡的代
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
3年前
Github标星5300+,专门为程序员开发文档开源管理系统,我粉了
!(https://oscimg.oschina.net/oscnet/a11909a041dac65b1a36b2ae8b9bcc5c432.jpg)码农那点事儿关注我们,一起学习进步!(https://oscimg.oschina.net/oscnet/f4cce1b7389cb00baaab228e455da78d0
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Stella981 Stella981
3年前
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法
Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法参考文章:(1)Google地球出现“无法连接到登录服务器(错误代码:c00a0194)”解决方法(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.codeprj.com%2Fblo
Stella981 Stella981
3年前
Flink SQL Window源码全解析
!(https://oscimg.oschina.net/oscnet/72793fbade36fc18d649681ebaeee4cdf00.jpg)(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fmp.weixin.qq.com%2Fs%3F__biz%3DMzU3MzgwNT