1. 程式人生 > 實用技巧 >幾種設計模式

幾種設計模式

設計模式

設計模式基礎

單一職責

為了實現高內聚,低耦合,做到職責分離,一個類只肩負一項職責

好處:提高程式碼的可讀性與可維護性。(除了類,在方法級別上亦當如此)

開閉原則

對擴充套件開放,對修改關閉。

分析:使用抽象來構建框架,實現來擴充套件細節,通過新增而不是修改來實現擴充

里氏替換原則

引用父類的地方透明地使用子類物件

分析:儘量不重寫父類中已經實現的方法

依賴倒置原則

高層不應該依賴底層,兩者都應該依賴於抽象;抽象不應該依賴於細節,細節應該依賴於抽象

分析:面向介面程式設計,介面制定約束,細節交給實現類

介面隔離

介面細化,類之間的依賴關係建立在最小介面上,介面的方法儘量少,服務於一個子模組

迪米特法則

最少知道,一個實體應該儘量減少與其他實體之間的相互作用,通過第三方轉發

單例模式

  • 類的例項物件只有一個,構造器通過private修飾
  • 執行緒安全
  • 禁止賦值和拷貝
  • 使用者通過介面獲取例項的引用
Lazy-Initialization
class Singleton{
private:
    Singleton(){
        std::cout<<"constructor called!"<<std::endl;
    }
    Singleton(Singleton&)=delete;
    Singleton& operator=(const Singleton&)=delete;
    static Singleton* m_instance_ptr;  //記憶體洩漏,可用智慧指標
public:
    ~Singleton(){
        std::cout<<"destructor called!"<<std::endl;
    }
    static Singleton* get_instance(){
        if(m_instance_ptr==nullptr){  //執行緒安全,可加鎖
              m_instance_ptr = new Singleton;
        }
        return m_instance_ptr;
    }
};
Singleton* Singleton::m_instance_ptr = nullptr;
區域性靜態變數
class Singleton
{
public:
    ~Singleton() {
        std::cout << "destructor called!" << std::endl;
    }
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    static Singleton& get_instance() {  //返回引用
        static Singleton instance;  //初始化如有併發,執行緒將會阻塞等待初始化結束
        return instance;            //生存期從宣告到程式結束
    }                             
private:
    Singleton() {
        std::cout << "constructor called!" << std::endl;
    }
};

工廠模式

簡單工廠
  • 一個工廠,多種產品,通過傳參指定具體產品
  • 通過工廠獲取虛基類指標,執行時多型
  • 建立邏輯對客戶端隱藏
class abstractProduct {
public:
    virtual void Operation() = 0;
    virtual ~abstractProduct() {}
};
class ProductA : public abstractProduct {
public:
    void Operation() { cout << "ProductA" << endl; }
};
class ProductB : public abstractProduct {
public:
    void Operation() { cout << "ProductB" << endl; }
};
class Factory {
public:
    abstractProduct* createProduct(int id) {
        switch (id) {
        case 1: return new ProductA(); break;
        case 2: return new ProductB(); break;
        default: break;
        }
    }
};
int main() {
    Factory* f = new Factory();
    f->createProduct(1)->Operation();  
    f->createProduct(2)->Operation();  
    delete f;
    return 0;
}
工廠方法模式
  • 符合擴充套件開放,修改關閉的原則
  • 工廠方法將類的例項化延遲到子類
class abstractProduct {
public:
    virtual ~abstractProduct() {}
    virtual void Operation() = 0;
};
class ProductA : public abstractProduct {
public:
    void Operation() { cout << "ProductA" << endl; }
};
class ProductB : public abstractProduct {
public:
    void Operation() { cout << "ProductB" << endl; }
};
class abstractFactory {
public:
    virtual abstractProduct* createProduct() = 0;
};
class FactoryA : public abstractFactory {
public:
    abstractProduct* createProduct() {
        return new ProductA();
    }
};
class FactoryB : public abstractFactory {
public:
    abstractProduct* createProduct() {
        return new ProductB();
    }
};
int main() {
    abstractFactory* factory = nullptr;
    factory = new FactoryA();
    factory->createProduct()->Operation();  
    factory = new FactoryB();
    factory->createProduct()->Operation();  
    delete factory;
    return 0;
}
抽象工廠模式
  • 每個工廠類可以生產多種產品
class Cpu {  //虛基類
public:
    virtual ~Cpu() {}
    virtual void Operation() = 0;
};
class amd3700x : public Cpu {
public:
    void Operation() { cout << "3700x" << endl; }
};
class intel10700k : public Cpu {
public:
    void Operation() { cout << "10700k" << endl; }
};

class Motherboard {  //虛基類
public:
    virtual ~Motherboard() {}
    virtual void Operation() = 0;
};
class x570 : public Motherboard {
public:
    void Operation() { cout << "x570" << endl; }
};
class z490 : public Motherboard {
public:
    void Operation() { cout << "z490" << endl; }
};

class abstractFactory {  //虛基類
public:
    virtual Cpu* createProductCpu() = 0;
    virtual Motherboard* createProductMotherboard() = 0;
};
class IntelFactory : public abstractFactory {
public:
    Cpu* createProductCpu() {
        return new intel10700k();
    }
    Motherboard* createProductMotherboard() {
        return new z490();
    }
};
class AmdFactory : public abstractFactory {
public:
    Cpu* createProductCpu() {
        return new amd3700x();
    }
    Motherboard* createProductMotherboard() {
        return new x570();
    }
};
int main() {
    abstractFactory* factory = nullptr;
    factory = new AmdFactory();
    factory->createProductCpu()->Operation();
    factory->createProductMotherboard()->Operation();

    factory = new IntelFactory();
    factory->createProductCpu()->Operation();
    factory->createProductMotherboard()->Operation();
    delete factory;
    return 0;
}

觀察者模式

定義了物件間一對多的依賴關係,當一個物件的狀態發生改變時,所有依賴於它的物件都得到通知並自動更新,是一種釋出-訂閱互動.

class Observer
{
public:
    virtual void update(string info) = 0;
};

class ObserverA :public Observer
{
    void update(string info) {
        std::cout << "ObserverA:" << info << std::endl;
    }
};

class ObserverB :public Observer
{
    void update(string info) {
        std::cout << "ObserverB:" << info << std::endl;
    }
};
class object
{
public:
    object() :information("notification") {};
    void attach(Observer* observer){
        observer_list.push_back(observer);
    }
    void detach(Observer* observer){
        observer_list.remove(observer);
    }
    void notify() {
        for (auto i : observer_list) {
            i->update(information);
        }
    }
    void set_status(string info){
        information = info;
    }
private:
    list<Observer*> observer_list;
    string information;
};
int main()
{
    object* lol = new object;
    ObserverA* Huya = new ObserverA;
    ObserverB* Douyu = new ObserverB;
    lol->attach(Huya);
    lol->attach(Douyu);
    lol->set_status("League of Legends World Championship begins");
    lol->notify();
    lol->detach(Huya);
    lol->detach(Douyu);
    delete lol;
    delete Huya;
    delete Douyu;
}

介面卡模式

定義包裝類Adapter,包裝Adaptee,使得Target能夠訪問Adaptee

class Target{
public:
	virtual void Request() {}
};

class Adaptee{
public:
	void Display(){
		cout << "do something here" << endl;
	}
};

class Adapter : public Target, public Adaptee
{
public:
	void Request(){
		this->Display();
	}
};

int main()
{
	Target* p = new Adapter();
	p->Request();
	delete p;  //釋放記憶體空間
	p = nullptr;  //避免野指標
	return 0;
}

策略模式

優點:擴充套件性良好,可以自由切換

缺點:策略類會增多,而且對外暴露

/*
 Context指向Strategy (由指標實現);
 Context通過Strategy 介面,呼叫一系列演算法;
 ConcreteStrategy 實現了一系列具體的演算法
*/
#include<iostream>
using namespace std;
class Strategy { // 抽象演算法類
public:
    virtual void AlgorithmInterface() = 0; 
    virtual ~Strategy() {}
};

class ConcreteStrategyA : public Strategy { 
public:
    void AlgorithmInterface() {
        cout << "ConcreteStrategyA" << endl;
    }
};

class ConcreteStrategyB : public Strategy { 
public:
    void AlgorithmInterface() {
        cout << "ConcreteStrategyB" << endl;
    }
};

class Context {  //上下文
private:
    Strategy* strategy;
public:
    Context(Strategy* s) { strategy = s; }
    void ContextInterface() { 
        strategy->AlgorithmInterface();
    }
};

int main() {
    Strategy* s = new ConcreteStrategyA();
    Context* c = new Context(s);
    c->ContextInterface();  
    delete s;
    delete c;
    return 0;
}