工廠模式詳解

參照原文:設計模式之三種工廠模式

簡單工廠模式

創建對象不再需要 new,我只需要將需要生產什麼東西告訴工廠,工廠就能生產出對應的對象實例

問題背景
大衆集團要生產汽車,但是不確定要生產哪幾個品牌的汽車

角色扮演
車: VwCar 類、AudiCar 類
工廠: Factory 類
客戶端:需要去實例化車的人或者其它代碼

適用場景
要生產的產品的數目和類型未知的時候

實現
兩種車:VwCar AudiCar

class Car {
    
};
class VwCar: public Car {
    public:
        VwCar() {
            printf("生產了一輛VwCar車\n");
        }
};
class AudiCar: public Car {
    public:
        AudiCar() {
            printf("生產了一輛AudiCar車\n");
        }
};

簡單工廠模式

//定義簡單工廠類
class Factory {
    public:
        Car* Product(std::string _s) {
            if (_s == "VW")
                return new VwCar();
            else if (_s == "AUDI")
                return new AudiCar();
            return nullptr;
        }
};

客戶端

int main() {
    Factory* factory = new Factory();
    factory->Product("VW");
    factory->Product("AUDI");
    return 0;
}

運行結果

生產了一輛VwCar車
生產了一輛AudiCar車

此時假如我又想要生產保時捷,只需要增加生產保時捷的方法,並且給工廠添加一條生產線,就可以通過告知工廠我想要生產保時捷,來得到保時捷這輛車

#include <string>
#include <cstdio>

//車
class Car {
    
};
class VwCar: public Car {
    public:
        VwCar() {
            printf("生產了一輛VwCar車\n");
        }
};
class AudiCar: public Car {
    public:
        AudiCar() {
            printf("生產了一輛AudiCar車\n");
        }
};
class PorscheCar: public Car {
    public:
        PorscheCar() {
            printf("生產了一輛PorscheCar車\n");
        }
};

//定義簡單工廠類
class Factory {
    public:
        Car* Product(std::string _s) {
            if (_s == "VW")
                return new VwCar();
            else if (_s == "AUDI")
                return new AudiCar();
            else if (_s == "Porsche") //增加一條生產線
                return new PorscheCar();
            return nullptr;
        }
};

int main() {
    Factory* factory = new Factory();
    factory->Product("VW");
    factory->Product("AUDI");
    factory->Product("Porsche");
    return 0;
}

工廠方法模式

問題背景
在簡單工廠模式中,如果我還要生賓利、布加迪,我不得不去修改簡單工廠類中的代碼,但是我並不想這樣做

角色扮演
車: VwCar 類、AudiCar 類
總工廠: Factory 抽象類,或者接口也行
子工廠: VwCarFactory 類、 AudiCarFactory 類
客戶端:需要去實例化車的人或者其它代碼

使用場景
要生產的產品的數目和類型未知的時候

實現
兩種車:VwCar AudiCar

class Car {
    
};
class VwCar: public Car {
    public:
        VwCar() {
            printf("生產了一輛VwCar車\n");
        }
};
class AudiCar: public Car {
    public:
        AudiCar() {
            printf("生產了一輛AudiCar車\n");
        }
};

總工廠

class Factory {
    public:
        virtual Car* Product() = 0;
};

子工廠

class VwCarFactory: public Factory {
    public:
        virtual Car* Product() {
            return new VwCar();
        }
};
class AudiCarFactory: public Factory {
    public:
        virtual Car* Product() {
            return new AudiCar();
        }
};

客戶端+測試

int main() {
    Factory* vw = new VwCarFactory();
    vw->Product();
    return 0;
}

可以看到,如果我生產了一輛 VwCar,不同於簡單工廠的是,這時是使用 VwCarFactory 去生產VwCar,煩人的條件語句沒有了。且作爲客戶端,我不需要關心 vw->Product(); 的具體實現,或者說不需要關心你這車怎麼生產的,你把車給我就好。

如果還需要生產保時捷,那麼新建一個工廠即可,不用更改代碼,利用多態,消除了煩人的條件語句

class PorscheCarFactory: public Factory {
	public:
		virtual Car* Product() { 
			return new PorscheCar(); 
		}  
};

優點
優點:相比於簡單工廠模式增加產品的時候只需要增加對應的類就可以,不用修改原來的代碼

抽象工廠模式

用工廠發放模式我不得不爲每一款車都建一個工廠,但是這樣似乎划不來,我希望同一系列的車都由同一個工廠來完成,例如奧迪車分爲高端奧迪和低端奧迪,將來可能還會有中端、頂端等等…
無論是低端奧迪還是高端奧迪,都是奧迪車

角色扮演
低端車接口: LowEndCar 類
車: VwLowEndCar 類 (低端大衆)
總工廠: Factory 抽象類
子工廠: VwCarFactory 類
客戶端:需要去實例化車的人或者其它代碼

實現
所有車的基類

class Car {

};

低端車的基類

class LowEndCar: public Car {
    //低端車都有的一些特徵方法,所有低端車都繼承自這個類
};

低端大衆車

class VwLowEndCar: public LowEndCar {
    public:
        VwLowEndCar() {
            printf("生產了一輛VwLowEndCar車\n");
        }
};

工廠

//總工廠
class Factory {
    public:
        virtual Car* Product()=0;
};
//子工廠
class VwLowEndCarFactroy: public Factory {
    public:
        virtual Car* Product() {
            return new VwLowEndCar();
        }
};

客戶端+測試

int main() {
    Factory* vw = new VwLowEndCarFactroy();
    vw->Product();
    return 0;
}

此時便可以添加高端車,添加奧迪車

#include <string>
#include <cstdio>

class Car {

};
class LowEndCar: public Car {
    //低端車都有的一些特徵方法,所有低端車都繼承自這個類
};
class HighEndCar: public Car {
    //高端車都有的一些特徵方法,所有高端車都繼承自這個類
};

//低端大衆和高端大衆
class VwLowEndCar: public LowEndCar {
    public:
        VwLowEndCar() {
            printf("生產了一輛VwLowEndCar車\n");
        }
};
class VwHighEndCar: public HighEndCar {
    public:
        VwHighEndCar() {
            printf("生產了一輛VwHihtEndCar車\n");
        }
};

//低端奧迪和高端奧迪
class AudiLowEndCar: public LowEndCar {
    public:
        AudiLowEndCar() {
            printf("生產了一輛AudiLowEndCar車\n");
        }
};
class AudiHighEndCar: public HighEndCar {
    public:
        AudiHighEndCar() {
            printf("生產了一輛AudiHighEndCar車\n");
        }
};

//總工廠
class Factory {
    public:
        virtual Car* ProductLowEndCar(){return nullptr;}
        virtual Car* ProductHighEndCar(){return nullptr;};
};
//生產大衆和奧迪的工廠,又分別能生產高端車和低端車
class VwFactroy: public Factory {
    public:
        virtual Car* ProductLowEndCar() {
            return new VwLowEndCar();
        }
        virtual Car* ProductHighEndCar() {
            return new VwHighEndCar();
        }
};
class AudiFactory: public Factory {
    public:
        virtual Car* ProductLowEndCar() {
            return new AudiLowEndCar();
        }
        virtual Car* ProductHighEndCar() {
            return new AudiHighEndCar();
        }
};

int main() {
    Factory* vw = new VwFactroy();
    vw->ProductLowEndCar();
    vw->ProductHighEndCar();
    Factory* audi = new AudiFactory();
    audi->ProductLowEndCar();
    audi->ProductHighEndCar();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章