c++工廠方法

本文通過運用設計模式比沒用設計模式的優勢在哪?

設計模式主要是要抓住穩定部分和易變部分,文章結尾會指出。

還指出工廠方法被設計出來,最開始想要解決的問題是什麼。

#include <iostream>
using namespace std;

//老代碼
class Fruit {
public:
    virtual void eaten() = 0;
    virtual ~Fruit() {}
};

class Apple : public Fruit {
public:
    void eaten() override {
        cout << "eat apple" << endl;
    }
};

class Orange : public Fruit {
public:
    void eaten() override {
        cout << "eat orange" << endl;
    }
};

class Banana: public Fruit {
public:
    void eaten() override {
        cout << "eat banana" << endl;
    }
};

//老代碼
class Man {
public:
    void eat() {
        Fruit *fruit = new Apple;	//這裏違背了"不與陌生人交流的原則"
        fruit->eaten();
        delete(fruit);
    }
};

//需求改變,Man可以喫任意的水果。注意fruit被喫掉後,需要在eat中析構。
//新增枚舉,修改Man::eat方法
//這種方法違背開閉原則,如果在添加水果種類,還要修改FruitType和Man2類。
enum FruitType {
    APPLE,
    ORANGE,
    BANANA
};

class Man2 {
public:
    void eat(FruitType type) {
        Fruit *fruit = nullptr;
        switch (type) {
            case APPLE:
                fruit = new Apple;
                break;
            case ORANGE:
                fruit = new Orange;
                break;
            case BANANA:
                fruit = new Banana;
                break;
        }
        fruit->eaten();
        delete(fruit);
    }

};

//工廠方法
//抽象工廠
//將來在新增水果類只需要增加對應的工廠方法。
class FruitFactory {
public:
    virtual Fruit* creatFruit() = 0;
    virtual ~FruitFactory() {}
};

class AppleFactory : public FruitFactory {
public:
    Fruit* creatFruit() override {
        return new Apple;
    }
};

class OrangeFactory : public FruitFactory {
public:
    Fruit* creatFruit() override {
        return new Orange;
    }
};

class BananaFactory : public FruitFactory {
public:
    Fruit* creatFruit() override {
        return new Banana;
    }
};

class Man3 {
public:
    void eat(FruitFactory *factory) {
        Fruit *fruit = factory->creatFruit();
        fruit->eaten();
        delete(fruit);
    }
};

int main()
{
    Man().eat();
    Man2().eat(BANANA);

    FruitFactory *factory = new OrangeFactory;
    Man3().eat(factory);
    delete(factory);
    return 0;
}

工廠方法穩定部分:Fruit/FruitFactory類,易變部分是:它們的子類。

策略方法讓Fruit類解耦,但是又new的存在還是要改變Man::eat函數,工廠方法最開始是爲了解決new帶來的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章