彩票代購網(wǎng)站建設(shè)百度怎么注冊(cè)自己的店鋪
作者:翟天保Steven
版權(quán)聲明:著作權(quán)歸作者所有,商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處
一、抽象工廠模式是什么?
? ? ? ?抽象工廠模式是一種創(chuàng)建型的軟件設(shè)計(jì)模式,該模式相當(dāng)于升級(jí)版的工廠模式。
? ? ? ?如果說工廠模式對(duì)應(yīng)一個(gè)產(chǎn)品系列,那抽象工廠就對(duì)應(yīng)了多個(gè)產(chǎn)品系列。比如工廠模式中有鞋子、衣服和褲子可以生產(chǎn),那抽象工廠模式就會(huì)衍生出耐克工廠和阿迪工廠,這兩個(gè)工廠分別生產(chǎn)各自品牌的鞋子、衣服和褲子,客戶只需要選擇具體工廠和想要的產(chǎn)品即可。如果想要替換產(chǎn)品系列,也只需要將具體工廠切換為別的品牌就行了。
? ? ? ?抽象工廠模式的優(yōu)點(diǎn):
- 具體類分離。具體產(chǎn)品類在具體工廠的實(shí)現(xiàn)中進(jìn)行了分離和歸類。
- 易于更換產(chǎn)品族。當(dāng)客戶想要改變整個(gè)產(chǎn)品族時(shí),只需要切換具體工廠即可。
- 利于產(chǎn)品一致性。當(dāng)產(chǎn)品族的各個(gè)產(chǎn)品需要在一起執(zhí)行時(shí),抽象工廠可以確保客戶只操作同系列產(chǎn)品,而不會(huì)進(jìn)行跨品牌的組合。
? ? ? 抽象工廠模式的缺點(diǎn):
- 不利于添加新種類產(chǎn)品。每加一個(gè)新的種類,如多一個(gè)項(xiàng)鏈類型的產(chǎn)品,那每一個(gè)具體工廠都要進(jìn)行代碼的擴(kuò)展,且破壞了原先規(guī)定的結(jié)構(gòu),違反了開閉原則。
二、抽象工廠模式
2.1 結(jié)構(gòu)圖
? ? ? ?客戶端即Main主函數(shù),選擇具體工廠(族),通過該工廠產(chǎn)生該系列下的具體產(chǎn)品(蘋果和香蕉),切換具體工廠,產(chǎn)生新系列的具體產(chǎn)品。
2.2 代碼示例
? ? ? ?場景描述:我聯(lián)系了一家中國工廠,品嘗該廠的蘋果和香蕉,吃完后又找到一家美國工廠,品嘗他家的蘋果和香蕉,對(duì)比下口感。
//Prodect.h
/****************************************************/
#pragma once
#include <iostream>using namespace std;// 抽象產(chǎn)品類
class Prodect
{
public:// 構(gòu)造函數(shù)Prodect(int price) :m_price(price) {};// 析構(gòu)函數(shù)virtual ~Prodect() {};// 獲取價(jià)格int getPrice() {return m_price;}
protected:// 產(chǎn)品價(jià)格int m_price;
};// 抽象產(chǎn)品細(xì)分-蘋果
class AppleProdect : public Prodect
{
public:// 構(gòu)造函數(shù)AppleProdect(int price, string color) :Prodect(price), m_color(color) {};// 析構(gòu)函數(shù)virtual ~AppleProdect() {};// 獲取顏色string getColor() {return m_color;}
protected:// 顏色string m_color;
};// 抽象產(chǎn)品細(xì)分-香蕉
class BananaProdect : public Prodect
{
public:// 構(gòu)造函數(shù)BananaProdect(int price) :Prodect(price) {};// 析構(gòu)函數(shù)virtual ~BananaProdect() {};
};// 具體產(chǎn)品-中國蘋果
class ChineseAppleProdect : public AppleProdect
{
public:// 構(gòu)造函數(shù)ChineseAppleProdect(int price, string color) :AppleProdect(price, color) {cout << "獲得了一個(gè)中國蘋果。" << endl;};// 析構(gòu)函數(shù)virtual ~ChineseAppleProdect() {cout << "吃掉了一個(gè)中國蘋果。" << endl;};
};// 具體產(chǎn)品-美國蘋果
class AmericanAppleProdect : public AppleProdect
{
public:// 構(gòu)造函數(shù)AmericanAppleProdect(int price, string color) :AppleProdect(price, color) {cout << "獲得了一個(gè)美國蘋果。" << endl;};// 析構(gòu)函數(shù)virtual ~AmericanAppleProdect() {cout << "吃掉了一個(gè)美國蘋果。" << endl;};
};// 具體產(chǎn)品-中國香蕉
class ChineseBananaProdect : public BananaProdect
{
public:// 構(gòu)造函數(shù)ChineseBananaProdect(int price) :BananaProdect(price) {cout << "獲得了一個(gè)中國香蕉。" << endl;};// 析構(gòu)函數(shù)virtual ~ChineseBananaProdect() {cout << "吃掉了一個(gè)中國香蕉。" << endl;};
};// 具體產(chǎn)品-美國香蕉
class AmericanBananaProdect : public BananaProdect
{
public:// 構(gòu)造函數(shù)AmericanBananaProdect(int price) :BananaProdect(price) {cout << "獲得了一個(gè)美國香蕉。" << endl;};// 析構(gòu)函數(shù)virtual ~AmericanBananaProdect() {cout << "吃掉了一個(gè)美國香蕉。" << endl;};
};
//Factory.h
/****************************************************/
#pragma once
#include <iostream>
#include "Prodect.h"using namespace std;// 抽象工廠類
class Factory
{
public:// 獲取蘋果virtual Prodect* getApple() = 0;// 獲取香蕉virtual Prodect* getBanana() = 0;
};// 具體工廠類-中國工廠
class ChineseFactory : public Factory
{
public:// 獲取蘋果virtual Prodect* getApple() {Prodect* prodect = new ChineseAppleProdect(5, "紅");return prodect;}// 獲取香蕉virtual Prodect* getBanana() {Prodect* prodect = new ChineseBananaProdect(3);return prodect;}
};// 具體工廠類-美國工廠
class AmericanFactory : public Factory
{
public:// 獲取產(chǎn)品virtual Prodect* getApple() {Prodect* prodect = new AmericanAppleProdect(4, "黑");return prodect;}// 獲取香蕉virtual Prodect* getBanana() {Prodect* prodect = new AmericanBananaProdect(2);return prodect;}
};
//main.cpp
/****************************************************/
#include <iostream>
#include <string>
#include "Factory.h"
#include "Prodect.h"using namespace std;int main()
{cout << "找到中國工廠。" << endl;Factory* factoryA = new ChineseFactory();Prodect *A = factoryA->getApple();Prodect *B = factoryA->getBanana();int applePrice = A->getPrice();int bananaPrice = B->getPrice();int sum = A->getPrice() + B->getPrice();cout << "蘋果價(jià)格:" << applePrice << "元。" << endl;cout << "香蕉價(jià)格:" << bananaPrice << "元。" << endl;cout << "累計(jì)消費(fèi):" << sum << "元。" << endl;cout << "中國蘋果" << dynamic_cast<AppleProdect*>(A)->getColor() << "色" << endl;delete A;delete B;delete factoryA;cout << "享用完畢。" << endl << endl;cout << "找到美國工廠。" << endl;Factory* factoryB = new AmericanFactory();Prodect *C = factoryB->getApple();Prodect *D = factoryB->getBanana();applePrice = C->getPrice();bananaPrice = D->getPrice();sum = C->getPrice() + D->getPrice();cout << "蘋果價(jià)格:" << applePrice << "元。" << endl;cout << "香蕉價(jià)格:" << bananaPrice << "元。" << endl;cout << "累計(jì)消費(fèi):" << sum << "元。" << endl;cout << "美國蘋果" << dynamic_cast<AppleProdect*>(C)->getColor() << "色" << endl;delete C;delete D;delete factoryB;cout << "享用完畢。不如China。" << endl;return 0;
}
? ? ? ?程序結(jié)果如下。
? ? ? ? 在上述示例中,我們可以看到,這兩個(gè)工廠都有同樣的系列產(chǎn)品(蘋果和香蕉),我想體驗(yàn)新的系列產(chǎn)品,只需要更換具體工廠即可。
三、總結(jié)
? ? ? ?我盡可能用較通俗的話語和直觀的代碼例程,來表述我對(duì)抽象工廠模式的理解,或許有考慮不周到的地方,如果你有不同看法歡迎評(píng)論區(qū)交流!希望我舉的例子能幫助你更好地理解抽象工廠模式。
? ? ? ?如果文章幫助到你了,可以點(diǎn)個(gè)贊讓我知道,我會(huì)很快樂~加油!