软件设计模式

设计模式的六大原则:

设计模式分类:

单例模式

概念:保证一个类只有一个实例,并提供一个访问它的全局访问点。

应用场景:打印机、文件系统、网络的config

实现方式:

饿汉式懒汉式两种实现:

饿汉式本身是线程安全的:

class Singleton{
private:
    static Singleton* instance;
    Singleton(){}
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
public:
    static Singleton* getInstance(){
        return instance;
    }
};

Singleton* Singleton::instance = new Singleton();

初始版本的懒汉式不是线程安全的:

class Singleton{
private:
    static Singleton* instance;
    Singleton(){}
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
public:
    static Singleton* getInstance(){
        if(instance == NULL){
            instance = new Singleton();
        }
        return instance;
    }
};
Singleton Singleton::instance = NULL;

问题:多线程时可能会有多个线程进入if(instance == NULL)的判断,从而重复创建实例。

改进版本1:加锁:

class Singleton{
private:
    static pthread_mutex_t mutex;
    static Singleton* instance;
    Singleton(){
        pthread_mutex_init(&mutex, NULL);
    }
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
public:
    static Singleton* getInstance(){
        pthread_mutex_lock(&mutex);
        if(instance == NULL){
            instance = new Singleton();
        }
        pthread_mutex_unlock(&mutex);
        retrun instance;
    }
};
Singleton& Singleton::instance = NULL;
pthread_mutex_t Singleton::mutex;

问题:每次获取实例对象时都要加锁判断是否为空,会造成线程阻塞。

改进版本2:双重判断:

class Singleton{
private:
    static Singleton* instance;
    pthread_mutex_t mutex;
    Singleton(){
        pthread_mutex_init(&mutex, NULL);
    }
    Singleton(const Singleton& temp){}
    Singleton& operator=(const Singleton& temp){}
public:
    static Singleton getInstance(){
        if(instance == NULL){
            pthread_mutex_lock(&mutex);
            if(instance == NULL){
                instance = new Singleton();
            }
            pthread_mutex_unlock(&mutex);
        }
        return instance;
    }
};
Singleton Singleton::instance = NULL;
pthread_mutex_t Singleton::mutex;

先进入第一个if(instance == NULL)的进程获得锁,并实例化对象,后进入的进程直接获取到它实例化的对象。

工厂模式

包括:

简单工厂模式:

class Operation{
public:
    int var1, var2;
    virtual double getResult(){
        double res = 0;
        return res;
    }
};

class AddOperation: public Operation{
public:
    virtual double getResult(){
        return var1 + var2;
    }
};

class SubOperation: public Operation{
public:
    virtual double getResult(){
        return var1 - var2;
    }
};

class MulOperation: public Operation{
public:
    virtual double getResult(){
        return var1 * var2;
    }
};

class DivOperation: public Operation{
public:
    virtual double getResult(){
        return var1 / var2;
    }
}

class Factory{
public:
    static Operation* createProduct(char ch){
        switch(ch){
            case '+': return new AddOperation();
            case '-': return new SubOperation();
            case '*': return new MulOperation();
            case '/': return new SubOperation();
            default: return new AddOperation();
        }
    }
};

int main(){
    Factory myFactory = new Factory();
    Operation* product = myFactory->createProduct('+');
    product->var1 = 1.5;
    product->var2 = 6.3;
    product->getResult();
    return 0;
}

问题:违背了开放封闭原则,每次添加新产品都要修改工厂端代码。

工厂方法模式:修正了简单工厂模式中不遵守开放封闭原则的缺陷。

class Operation{
public:
    int var1, var2;
    virtual double getResult(){
        double res = 0;
        return res;
    }
};

class AddOperation : public Operation{
public:
    virtual double getResult(){
        return var1 + var2;
    }
};

class SubOperation : public Operation{
public:
    virtul double getResult(){
        return var1 - var2;
    }
};

class MulOperation : public Operation{
public:
    virtual double getResult(){
        return var1 * var2;
    }
};

class DivOperation : public Operation{
public:
    virtual double getResult(){
        return var1 / var2;
    }
};

class Factory{
public:
    virtual Operation* createProduct() = 0;
};

class AddFactroy : public Factory{
public:
    virtual Operation* createProduct(){
        return new AddOperation();
    }
};

class SubFactory : public Factory{
public:
    virtual Operation* createProduct(){
        return new SubOperation();
    }
};

class MulFactory : public Factory{
public:
    virtual Operation* createProduct(){
        return new MulOperation();
    }
};

class DivFactory : public Factory{
public:
    virtual Operation* createProduct(){
        return new DivOperation();
    }
};

int main(){
    Factory* myFac = new AddFactory();
    Operation* myOper = myFac->createProduct();
    myOper->var1 = 2;
    myOper->var2 = 6;
    myOper->getResult();
    return 0;
}

抽象工厂模式:扩大了工厂能够生产产品范围,允许工厂生产一个产品族。

class Operation_Pos{
public:
    int var1, var2;
    virtual double getResult(){
        int res = 0;
        return 0;
    }
};

class Operation_Neg{
public:
    int var1, var2;
    virtual double getResult(){
        int res = 0;
        return 0;
    }
};

class AddOperation_Pos{
public:
    virtual double getResult(){
        return var1 + var2;
    }
};

class AddOperation_Neg{
public:
    virtual double getResult(){
        return -(var1 + var2);
    }
};

class SubOperation_Pos{
public:
    virtual double getResult(){
        return var1 - var2;
    }
};

class SubOperation_Neg{
public:
    virtual double getResult(){
        return -(var1 - var2);
    }
};

class MulOperation_Pos{
public:
    virtual double getResult(){
        return var1 * var2;
    }
};

class MulOperation_Neg{
public:
    virtual double getResult(){
        return - (var1 * var2);
    }
};

class DivOperation_Pos{
public:
    virtual double getResult(){
        return var1 / var2;
    }
};

class DivOperation_Neg{
public:
    virtual double getResult(){
        return -(var1 / var2);
    }
};

class Factory{
public:
    virtual Operation_Pos* createProduct_Pos() = 0;
    virtual Operation_Neg* createProduct_Neg() = 0;
}

class AddFactory : public Factory{
public:
    virtual Operation_Pos* createProduct_Pos(){
        return new AddOperation_Pos();
    }

    virtual Operation_Neg* createProduct_Neg(){
        return new AddOperation_Neg();
    }
};

class SubFactory : public Factory{
public
    virtual Operation_Pos* createProduct_Pos(){
        return new SubOperation_Pos();
    }

    virtual Operation_Neg* createProduct_Neg(){
        return new SubOperation_Neg();
    }
};

class MulFactory : public Factory{
public:
    virtual Operation_Pos* createProduct_Pos(){
        return new MulOperation_Pos();
    }

    virtual Operation_Neg* createProduct_Neg(){
        return new MulOperation_Neg();
    }
};

class DivFactory : public Factory{
public:
    virtual Operation_Pos* createProduct_Pos(){
        return new DivOperation_Pos();
    }

    virtual Operation_Neg* createProduct_Neg(){
        return new DivOperation_Neg();
    }
};

int main(){
    Factory myFac = new AddFactory();
    Operation_Pos* myOper = myFac->createProduct_Pos();
    myOper->val1 = 2;
    myOper->val2 = 6;
    myOper->getResult();

    Operation_Neg* myOper_Neg = myFac->createProduct_Neg();
    myOper_Neg->val1 = 8;
    myOper_Neg->Val2 = 6;
    myOper_Neg->getResult();
}

观察者模式

概念:定义一种一对多的关系,让多个观察者同时监听一个被观察对象,当被观察对象的状态发生变化时,会通知所有的观察对象,使他们能够更新自己的状态。

class Subject;

class Observer{
protected:
    string name;
    Subject* sub;
public:
    Observer(string name, Subject* sub){
        this->name = name;
        this->sub = sub;
    }
    virtual void update() = 0;
};

class StockObserver : public Observer{
public:
    StockObserver(string name, Subject* sub) : Observer(name, sub){}

    void update();
}

class NBAObserver : public Observer{
public:
    NBAObserver(string name, Subject* sub) : Observer(name, sub){}

    void update();
};

class Subject{
private:
    list<Observer*> obs;
public:
    string action;
    virtual void attach(Obserser*) = 0;
    virtual void detach(Observer*) = 0;
    virtual void notify() = 0;
};

class Secretary : public Subject{
public:
    void attch(Oberser* observer){
        obs.push_back(observer);
    }

    void detach(Observer* observer){
        list<Observer*>:: iterator iter = observers.begin();
        while(iter != observers.end()){
            if((*iter) == observer){
                observers.erase(iter);
                return;
            }
        }
        ++iter;
    }

    void notify(){
        list<Observer*>::iterator iter = observers.begin();
        while(iter != observers.end()){
            (*iter)->update();
            ++iter;
        }
    }
};

void StockObserver::update(){
    cout << name << "msg received." << sub->action << endl;
    if(sub->action == "sos"){
        cout << "run!" << endl;
    }
}

void NBAObserver::update(){
    cout << name << "msg received." << sub->action << endl;
    if(sub->action == "sos"{
        cout << "run!!!" << endl;
    })
}

int main(){
    Subject* secretary = new Secretary();

    Observer* a = new NBAObserver("NBA_a", secretary);
    Observer* b = new NBAObserver("NBA_b", secretary);

    Observer* c = new StockObserver("Stock_c", secretary);
    Observer* d = new StockObserver("Stock_d", secretary);

    secretary->attach(a);
    secretary->attach(b);
    secretary->attach(c);
    secretary->attach(d);

    secretary->action = "hahaha";
    secretary->notify();
    cout << endl;

    secretary->action = "sos";
    secretary->notify();
    cout << endl;
    
    return 0;
}