設(shè)計(jì)模式之工廠模式
掃描二維碼
隨時(shí)隨地手機(jī)看文章
經(jīng)過一周的工作是不是疲憊不堪?
快來讀讀我的文章充充電吧~
(沒 時(shí) 間 的 可 以 先 收 藏 留 著 周 末 看 看 哈 )
工廠模式大體可以分為
●簡(jiǎn)單工廠模式
●工廠方法模式
●抽象工廠模式
enum class BallEnum { BasketBall = 1, SocketBall = 2 };class Ball {public:Ball() {}virtual ~Ball() {}virtual void Play() {}};class BasketBall : public Ball {public:void Play() override { std::cout << "play basketball \n"; }};class SocketBall : public Ball {public:void Play() override { std::cout << "play socketball \n"; }};class SimpleFactory {public:static Ball* CreateBall(BallEnum type);};Ball* SimpleFactory::CreateBall(BallEnum type) {switch (type) {case BallEnum::BasketBall:return new BasketBall();case BallEnum::SocketBall:return new SocketBall();}return nullptr;}int main() {Ball* basket = SimpleFactory::CreateBall(BallEnum::BasketBall);basket->Play();Ball* socket = SimpleFactory::CreateBall(BallEnum::SocketBall);socket->Play();return 0;}
在簡(jiǎn)單工廠方法中,有一個(gè)專門的工廠類,根據(jù)不同的參數(shù)返回不同具體產(chǎn)品類的實(shí)例,這些具體產(chǎn)品可以抽象出同一個(gè)抽象產(chǎn)品,即有一個(gè)共同的父類。 通過上述代碼您可能也看到了簡(jiǎn)單工廠方法的優(yōu)點(diǎn),實(shí)現(xiàn)了對(duì)象的創(chuàng)建和使用邏輯分離,只需要傳入不同參數(shù),就可以獲得特定具體類的實(shí)例。但簡(jiǎn)單工廠方法也有些缺點(diǎn),當(dāng)增加了新的產(chǎn)品,就需要修改工廠類的創(chuàng)建邏輯,如果產(chǎn)品類型較多,就可能造成工廠類邏輯過于復(fù)雜,不利于系統(tǒng)的維護(hù),適用于具體產(chǎn)品類型比較少并且以后基本不會(huì)新加類型的場(chǎng)景,這樣工廠類業(yè)務(wù)邏輯不會(huì)太過復(fù)雜。
為了解決上面簡(jiǎn)單工廠方法模式的缺點(diǎn),進(jìn)一步抽象出了工廠方法模式,工廠類不再負(fù)責(zé)所有產(chǎn)品的構(gòu)建,每一個(gè)具體產(chǎn)品都有一個(gè)對(duì)應(yīng)的工廠,這樣在新加產(chǎn)品時(shí)就不會(huì)改動(dòng)已有工廠類的創(chuàng)建邏輯。這些工廠也會(huì)抽象出一個(gè)抽象工廠。可以理解為有四種角色,抽象產(chǎn)品,具體產(chǎn)品,抽象工廠,具體工廠,其實(shí)就是把簡(jiǎn)單工廠模式中的工廠類做進(jìn)一步抽象,看代碼吧:
enum class BallEnum { BasketBall = 1, SocketBall = 2 };class Ball {public:Ball() {}virtual ~Ball() {}virtual void Play() {}};class BasketBall : public Ball {public:void Play() override { std::cout << "play basketball \n"; }};class SocketBall : public Ball {public:void Play() override { std::cout << "play socketball \n"; }};class FactoryBase {public:virtual ~FactoryBase() {}virtual Ball* CreateBall() = 0;};class BasketBallFactory : public FactoryBase {public:Ball* CreateBall() override { return new BasketBall(); }};class SocketBallFactory : public FactoryBase {public:Ball* CreateBall() override { return new SocketBall(); }};int main() {FactoryBase* factory;BallEnum ball_type = BallEnum::SocketBall;switch (ball_type) {case BallEnum::BasketBall:factory = new BasketBallFactory();break;case BallEnum::SocketBall:factory = new SocketBallFactory();break;}Ball* ball = factory->CreateBall();ball->Play();return 0;}
工廠模式提高了系統(tǒng)的可擴(kuò)展性,完全符合開閉原則,當(dāng)新加具體產(chǎn)品時(shí),完全不會(huì)對(duì)已有系統(tǒng)有任何修改。當(dāng)不知道以后會(huì)有多少具體產(chǎn)品時(shí)可以考慮使用工廠模式,因?yàn)椴粫?huì)降低現(xiàn)有系統(tǒng)的穩(wěn)定性。但是它也有缺點(diǎn),每當(dāng)新加一個(gè)產(chǎn)品時(shí),不僅需要新加一個(gè)對(duì)應(yīng)的產(chǎn)品類,同時(shí)還需要新加一個(gè)此產(chǎn)品對(duì)應(yīng)的工廠,系統(tǒng)的復(fù)雜度比較高。怎么解決呢,可以再抽象一下:
在工廠方法中,每一個(gè)抽象產(chǎn)品都會(huì)有一個(gè)抽象工廠,這樣新增一個(gè)產(chǎn)品時(shí)都會(huì)新增兩個(gè)類,一個(gè)是具體產(chǎn)品類,一個(gè)是具體工廠類,我們可以考慮多個(gè)抽象產(chǎn)品對(duì)應(yīng)一個(gè)抽象工廠,這樣可以有效減少具體工廠類的個(gè)數(shù),見如下代碼:
enum class BallEnum { BasketBall = 1, SocketBall = 2 };class Ball {public:Ball() {}virtual ~Ball() {}virtual void Play() {}};class BasketBall : public Ball {public:void Play() override { std::cout << "play basketball \n"; }};class SocketBall : public Ball {public:void Play() override { std::cout << "play socketball \n"; }};class Player {public:Player() {}virtual ~Player() {}virtual void Name() {}};class BasketBallPlayer : public Player {public:void Name() override { std::cout << "BasketBall player \n"; }};class SocketBallPlayer : public Player {public:void Name() override { std::cout << "SocketBall player \n"; }};class FactoryBase {public:virtual ~FactoryBase() {}virtual Ball* CreateBall() = 0;virtual Player* CreatePlayer() = 0;};class BasketBallFactory : public FactoryBase {public:Ball* CreateBall() override { return new BasketBall(); }Player* CreatePlayer() override { return new BasketBallPlayer(); }};class SocketBallFactory : public FactoryBase {public:Ball* CreateBall() override { return new SocketBall(); }Player* CreatePlayer() override { return new SocketBallPlayer(); }};int main() {FactoryBase* factory;BallEnum ball_type = BallEnum::SocketBall;switch (ball_type) {case BallEnum::BasketBall:factory = new BasketBallFactory();break;case BallEnum::SocketBall:factory = new SocketBallFactory();break;}Ball* ball = factory->CreateBall();Player* player = factory->CreatePlayer();ball->Play();player->Name();return 0;}
總結(jié)
往期推薦
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!





