設(shè)計(jì)模式之抽象工廠模式(學(xué)習(xí)筆記)
定義
抽象工廠模式是一種創(chuàng)建型設(shè)計(jì)模式,它提供一個(gè)接口,用于創(chuàng)建一系列相關(guān)或依賴的對(duì)象,而無(wú)需指定它們的具體類。抽象工廠模式將對(duì)象的創(chuàng)建過(guò)程抽象化,允許子類通過(guò)實(shí)現(xiàn)具體工廠類來(lái)定制對(duì)象的創(chuàng)建。
為什么使用抽象工廠模式
-
產(chǎn)品族的一致性
-
抽象工廠模式確保同一產(chǎn)品族中的對(duì)象之間的一致性。
-
部分遵循開閉原則
-
可以通過(guò)添加新的具體工廠類來(lái)擴(kuò)展新的產(chǎn)品族,而不需要修改現(xiàn)有代碼,符合開閉原則。
-
增加新的產(chǎn)品類型時(shí),需要修改抽象工廠接口及其所有具體實(shí)現(xiàn),不完全符合開閉原則。
-
隱藏對(duì)象創(chuàng)建細(xì)節(jié)
-
抽象工廠模式將具體產(chǎn)品的創(chuàng)建過(guò)程隱藏起來(lái),客戶端只需要使用工廠提供的接口來(lái)獲取對(duì)象。
實(shí)現(xiàn)步驟
-
定義抽象產(chǎn)品類
-
定義所有具體產(chǎn)品類的共同接口,客戶端將通過(guò)這個(gè)接口來(lái)使用具體產(chǎn)品。
-
實(shí)現(xiàn)具體產(chǎn)品類
-
實(shí)現(xiàn)產(chǎn)品接口的具體產(chǎn)品類,這些類包含了產(chǎn)品的實(shí)際業(yè)務(wù)邏輯。
-
定義抽象工廠類
-
定義一個(gè)抽象工廠類,包含用于創(chuàng)建一系列相關(guān)或依賴對(duì)象的抽象方法,子類將實(shí)現(xiàn)這些方法來(lái)創(chuàng)建具體產(chǎn)品對(duì)象。
-
實(shí)現(xiàn)具體工廠類
-
繼承抽象工廠類并實(shí)現(xiàn)其抽象方法,具體工廠類負(fù)責(zé)創(chuàng)建具體產(chǎn)品對(duì)象。
優(yōu)缺點(diǎn)和適用場(chǎng)景
優(yōu)點(diǎn)
-
產(chǎn)品族的一致性
-
確保同一產(chǎn)品族中的對(duì)象之間的一致性。
-
部分符合開閉原則
-
可以通過(guò)添加新的具體工廠類來(lái)擴(kuò)展新的產(chǎn)品族,符合開閉原則。
-
隱藏對(duì)象創(chuàng)建細(xì)節(jié)
-
客戶端無(wú)需知道具體產(chǎn)品的創(chuàng)建過(guò)程,只需要通過(guò)工廠接口獲取對(duì)象。
缺點(diǎn)
-
增加系統(tǒng)復(fù)雜性
-
引入了更多的類,增加了系統(tǒng)的復(fù)雜性。
-
不完全符合開閉原則
-
增加新的產(chǎn)品類型時(shí),需要修改抽象工廠接口及其所有具體實(shí)現(xiàn),不完全符合開閉原則。
適用場(chǎng)景
-
系統(tǒng)需要?jiǎng)?chuàng)建一系列相關(guān)或依賴的對(duì)象
-
當(dāng)系統(tǒng)需要?jiǎng)?chuàng)建一系列相關(guān)或依賴的對(duì)象,并且確保這些對(duì)象之間的一致性時(shí),適合使用抽象工廠模式。
-
產(chǎn)品族擴(kuò)展
-
當(dāng)系統(tǒng)需要通過(guò)增加新的產(chǎn)品族來(lái)擴(kuò)展功能,而不需要修改現(xiàn)有代碼時(shí),適合使用抽象工廠模式。
簡(jiǎn)單工廠模式、工廠方法模式與抽象工廠模式的比較
|
特性
|
簡(jiǎn)單工廠模式
|
工廠方法模式
|
抽象工廠模式
|
|
創(chuàng)建對(duì)象的職責(zé)
|
單一工廠類負(fù)責(zé)所有產(chǎn)品創(chuàng)建
|
子類決定創(chuàng)建具體對(duì)象
|
子類決定創(chuàng)建一系列相關(guān)對(duì)象
|
|
遵循開閉原則
|
不符合,增加新產(chǎn)品需修改工廠類
|
符合,增加新產(chǎn)品無(wú)需修改工廠類
|
部分符合,增加產(chǎn)品族符合
|
|
系統(tǒng)復(fù)雜性
|
較低
|
中等
|
較高
|
|
產(chǎn)品族一致性支持
|
不支持
|
不支持
|
支持
|
咖啡店的例子
我們可以使用抽象工廠模式來(lái)實(shí)現(xiàn)一個(gè)咖啡店系統(tǒng),該系統(tǒng)可以創(chuàng)建不同種類的咖啡及其配套的杯子和勺子。
#include <iostream> #include <memory> #include <string> // 抽象產(chǎn)品類:咖啡 class Coffee { public: virtual ~Coffee() {} virtual std::string getDescription() const = 0; virtual double cost() const = 0; }; // 具體產(chǎn)品類:美式咖啡 class Americano : public Coffee { public: std::string getDescription() const override { return "Americano"; } double cost() const override { return 5.0; } }; // 抽象產(chǎn)品類:咖啡杯 class CoffeeCup { public: virtual ~CoffeeCup() {} virtual std::string getDescription() const = 0; }; // 具體產(chǎn)品類:美式咖啡杯 class AmericanoCup : public CoffeeCup { public: std::string getDescription() const override { return "Americano Cup"; } }; // 抽象產(chǎn)品類:咖啡勺 class CoffeeSpoon { public: virtual ~CoffeeSpoon() {} virtual std::string getDescription() const = 0; }; // 具體產(chǎn)品類:美式咖啡勺 class AmericanoSpoon : public CoffeeSpoon { public: std::string getDescription() const override { return "Americano Spoon"; } }; // 抽象工廠類 class CoffeeFactory { public: virtual ~CoffeeFactory() {} virtual std::shared_ptr<Coffee> createCoffee() const = 0; virtual std::shared_ptr<CoffeeCup> createCoffeeCup() const = 0; virtual std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const = 0; }; // 具體工廠類:美式咖啡工廠 class AmericanoFactory : public CoffeeFactory { public: std::shared_ptr<Coffee> createCoffee() const override { return std::make_shared<Americano>(); } std::shared_ptr<CoffeeCup> createCoffeeCup() const override { return std::make_shared<AmericanoCup>(); } std::shared_ptr<CoffeeSpoon> createCoffeeSpoon() const override { return std::make_shared<AmericanoSpoon>(); } }; int main() { // 創(chuàng)建美式咖啡及其配套杯子和勺子 std::shared_ptr<CoffeeFactory> americanoFactory = std::make_shared<AmericanoFactory>(); std::shared_ptr<Coffee> americano = americanoFactory->createCoffee(); std::shared_ptr<CoffeeCup> americanoCup = americanoFactory->createCoffeeCup(); std::shared_ptr<CoffeeSpoon> americanoSpoon = americanoFactory->createCoffeeSpoon(); std::cout << "Coffee: " << americano->getDescription() << ", Cost: " << americano->cost() << std::endl; std::cout << "Cup: " << americanoCup->getDescription() << std::endl; std::cout << "Spoon: " << americanoSpoon->getDescription() << std::endl; return 0; }

浙公網(wǎng)安備 33010602011771號(hào)