一些简单的设计模式

作为补充,开始了解一些简单的设计模式。

应该掌握的

  • 单例
  • 工厂
  • 代理
  • 策略模式
  • 模板方法

简单工厂模式

考虑用一个单独的类去创建实例。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#define DBG_MACRO_NO_WARNING 
#include<dbg.h>
using namespace std;

template<typename T>
class Operation{
public:
    Operation(){}
    Operation(const T& n1,const T& n2): N1(n1), N2(n2){}
    virtual T getResult() const{
        return 0;
    }
    void setA(const T& val){N1 = val;}
    void setB(const T& val){N2 = val;}
protected:
    T N1;
    T N2;
};

template<typename T>
class OperationPlus: public Operation<T>{
public:
    OperationPlus(const T n1, const T n2): Operation<T>(n1, n2){};
    T getResult() const override{
        return this->N1 + this->N2;
    }
};

template<typename T>
class Factory{
public:
    Operation<T>* createOperation(const T& a, const T& b, string oper){
        if(oper == "+"){
            op = new OperationPlus<T>(a, b);
        }
        return op;
    }
    virtual ~Factory(){
        delete op;
    }
private:
    Operation<T> *op;
};

int main(){
    Factory<int> factory;
    auto oper = factory.createOperation(1, 2, "+");
    dbg(oper->getResult());
}

策略模式

定义了算法家族,分别封装起来,可以相互替换。使得算法的变化不影响客户。

把某个实现方法抽象为接口,使用组合而不是继承。

想修改具体某个算法时,不需要其用户改变。

一言以蔽之,使用组合把算法做成接口。

单一职责原则

就一个类而言,应该仅有一个引起它变化的原因。

开放-封闭原则

软件实体应该可以扩展,但是不可修改。

依赖倒转原则

抽象不应该依赖细节,细节应该依赖于抽象。针对接口编程。

里氏代换原则

子类必须能够替换掉他们的父类。

装饰模式

动态地给一个对象添加一些额外的职责。

代理模式

为其他对象提供一种代理以控制对这个对象的访问。Proxy 类里面有一个 RealSubject,真实访问类。

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪个类。即将一个类的实例化延迟到子类。

简单工厂实际上就是工厂方法去掉 Creator。简单工厂只有一种生产方式,而工厂方法可以实现多种工厂以应对多种生产方式。又或者可以传递参数给工厂,实现工厂的动态变化生产。

模板方法模式

定义一个操作中算法的骨架,将一些步骤延迟到子类。模板方法使得子类能不改变算法的结构也能重定义算法的某些步骤。

原型模式

用原型实例创建指定对象的种类,并通过拷贝创建新的对象。

抽象工厂方法

实际上抽象工厂就是多个工厂方法模式,区别就是在于抽象工厂会产生多种类的实例。而工厂方法仅仅是一种类。在抽象工厂中,任何一个工厂实例都有能力生产各种实例。

抽象工厂提供了一个创建实例的接口,用于创建相关或依赖对象的家族,但是不需要指定具体的类。

单例模式

保证一个类仅有一个实例,且提供一个访问它的全局访问点。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class singleton {
private:
    singleton() {}
    static singleton *p;
public:
    static singleton *instance();
};

singleton *singleton::p = nullptr;

singleton* singleton::instance() {
    if (p == nullptr)
        p = new singleton();
    return p;
}

线程安全的版本(定义时即初始化)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class singleton {
private:
    singleton() {}
    static singleton *p;
public:
    static singleton *instance();
};

singleton *singleton::p = new singleton();
singleton* singleton::instance() {
    return p;
}
0%