設計模式已經經歷了很長一段時間的發展,它們提供了軟件開發過程當中面臨的通常問題的最佳解決方案。學習這些模式有助於經驗不足的開發人員經過一種簡單快捷的方式來學習軟件設計。python
通常咱們會說設計模式一共有23種,整體來講設計模式分爲三大類:ios
建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。程序員
結構型模式,共七種:適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。express
行爲型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、解釋器模式。設計模式
今天主要是分析 簡單工廠模式、工廠模式和抽象工廠模式的區別,因此這裏就簡單介紹一下設計模式的概念。微信
做者:良知猶存框架
轉載受權以及圍觀:歡迎添加微信公衆號:羽林君函數
網上的不少資料都是在闡述着:工廠模式的好處就是解耦。相信你們對解耦這個詞也不陌生,那解耦究竟有什麼好處呢?學習
1.爲了提升內聚(Cohesion)和鬆耦合(Coupling),咱們常常會抽象出一些類的公共接口以造成抽象基類或者接口。這樣咱們能夠經過聲明一個指向基類的指針來指向實際的子類實現,達到了多態的目的。這裏很容易出現的一個問題 n 多的子類繼承自抽象基類,咱們不得不在每次要用到子類的地方就編寫諸如 new ×××;的代碼。這裏帶來兩個問題:測試
客戶程序員必須知道實際子類的名稱(當系統複雜後,命名將是一個很很差處理的問題,爲了處理可能的名字衝突,有的命名可能並非具備很好的可讀性和可記憶性,就姑且不論不一樣程序員千奇百怪的我的偏好了)。程序的擴展性和維護變得愈來愈困難。
2.還有一種狀況就是在父類中並不知道具體要實例化哪個具體的子類。這裏的意思爲:假設咱們在類 A 中要使用到類 B,B 是一個抽象父類,在 A 中並不知道具體要實例化那一個 B 的子類,可是在類 A 的子類 D 中是能夠知道的。在 A 中咱們沒有辦法直接使用相似於 new ×××的語句,由於根本就不知道×××是什麼。
以上兩個問題也就引出了工廠模式的兩個最重要的功能:
定義建立對象的接口,封裝了對象的建立;
使得具體化類的工做延遲到了子類中。
對於工廠模式,爲了使其能更好的解決多種狀況的問題,將其分爲三類:簡單工廠模式(Simple Factory),工廠方法模式(Factory Method),抽象工廠模式(Abstract Factory)。
GOAT
常用會遇到一些設計模式的使用,可是不多去細究裏面的區別,這把就讓我來你們分享一下,我認知中的這三種工廠模式。
咱們把被建立的對象稱爲「產品」,把建立產品的對象稱爲「工廠」。若是要建立的產品很少,只要一個工廠類就能夠完成,這種模式叫「簡單工廠模式」。
是由一個工廠對象決定建立出哪種產品類的實例。
簡單工廠模式中包含的角色及其相應的職責以下:
工廠角色(Creator):這是簡單工廠模式的核心,由它負責建立全部的類的內部邏輯。固然工廠類必須可以被外界調用,建立所須要的產品對象。
抽象(Product)產品角色:簡單工廠模式所建立的全部對象的父類,注意,這裏的父類能夠是接口也能夠是抽象類,它負責描述全部實例所共有的公共接口。
具體產品(Concrete Product)角色:簡單工廠所建立的具體實例對象,這些具體的產品每每都擁有共同的父類。
定義一個建立產品對象的工廠接口,將產品對象的實際建立工做推遲到具體子工廠類當中。這知足建立型模式中所要求的「建立與使用相分離」的特色。
#include <iostream> using namespace std; enum Product_Type { Product1_, Product2_, }; class AbstractProduct //抽象(Product)產品角色 { public: AbstractProduct() {} virtual ~AbstractProduct() {} virtual void Show() = 0; }; class Product1 : public AbstractProduct //具體產品(Concrete Product)角色 { private: /* data */ public: Product1(/* args */); ~Product1(); void Show() { std::cout<< "product1"<<std::endl; } }; Product1::Product1() { } Product1::~Product1() { } class Product2 : public AbstractProduct //具體產品(Concrete Product)角色 { private: /* data */ public: void Show() { std::cout<< "product2"<<std::endl; } }; class Factory //工廠角色(Creator) { public: AbstractProduct *CreateProduct(Product_Type type) { switch (type) { case Product1_/* constant-expression */: /* code */ return new Product1(); case Product2_: return new Product2(); default: return NULL; } } }; int main(int argc, char **argv) { Factory *new_factory = new Factory(); AbstractProduct *new_product1 = new_factory->CreateProduct(Product1_); new_product1->Show(); AbstractProduct *new_product2 = new_factory->CreateProduct(Product2_); new_product2->Show(); delete new_factory,new_product1,new_product2; new_factory = NULL; new_product1 = NULL; new_product2 = NULL; }
#!/usr/bin/python3 from enum import Enum ProducType = Enum(('ProducType'),('product1_','product2_','product_3')) class AbstractProduct(object): def show(self): pass class Product1(AbstractProduct): def show(self): print("Product1") class Product2(AbstractProduct): def show(self): print("Product2") class AbcFactory(object): def crete_product(self): pass class Factory(AbcFactory): def crete_product(self,type): product_type = { ProducType.product1_ : Product1(), ProducType.product2_ : Product2() } return product_type.get(type,None) if __name__ == "__main__": new_factory = Factory() product1 = new_factory.crete_product(ProducType.product1_) product1.show() product2 = new_factory.crete_product(ProducType.product2_) product2.show()
一、簡單工廠模式最大的優勢在於工廠類中能夠判斷客戶的的選擇來動態實例化相關的類,對於客戶端來講,去除了具體產品的依賴。
二、缺點就是:很明顯工廠類集中了對全部實例建立的邏輯,若是咱們要新增子類或者改變方法的話,就得每次都修改工廠類裏面的代碼,工廠類中的代碼就會十分臃腫,這就等於說咱們不進開放了擴展,還開放了修改,這樣就違反了開放-封閉原則。
你可能在不知不覺中已經用到過這種模式了,但簡單工廠模式並不屬於23種設計模式之一,下面介紹他的改進版本:工廠方法模式。
工廠方法模式是一種建立型設計模式, 其在父類中提供一個建立對象的方法, 容許子類決定實例化對象的類型。
抽象工廠類廠(AbstractFactory):工廠方法模式的核心類,提供建立具體產品的接口,由具體工廠類實現。
具體工廠類(Producer):繼承於抽象工廠,實現建立對應具體產品對象的方式。
抽象產品類(Factory):它是具體產品繼承的父類(基類)。
具體產品類(Factory1):具體工廠所建立的對象,就是此類。
#include <iostream> using namespace std; class AbstractProduct { public: AbstractProduct() {} virtual ~AbstractProduct() {} virtual void Show() = 0; }; class Product1 : public AbstractProduct { private: /* data */ public: Product1(/* args */); ~Product1(); void Show() { std::cout<< "product1"<<std::endl; } }; Product1::Product1(/* args */) { } Product1::~Product1() { } class Product2 : public AbstractProduct { private: /* data */ public: void Show() { std::cout<< "product2"<<std::endl; } }; class Factory { public: virtual ~Factory(){}; virtual AbstractProduct *CreateProduct() = 0; }; class Factory1 : Factory { public: AbstractProduct * CreateProduct(void) { return new Product1(); } }; class Factory2 :Factory { public: AbstractProduct * CreateProduct(void) { return new Product2(); } }; int main(int argc, char **argv) { Factory1 *new_factory = new Factory1(); AbstractProduct *new_product1 = new_factory->CreateProduct(); new_product1->Show(); delete new_factory; new_factory = NULL; Factory2 * new_factory2 = new Factory2(); AbstractProduct *new_product2 = new_factory2->CreateProduct(); new_product2->Show(); delete new_factory2; new_factory2 = NULL; }
#!/usr/bin/python3 class AbstractProduct(object): def show(self): pass class Product1(AbstractProduct): def show(self): print("Product1") class Product2(AbstractProduct): def show(self): print("Product2") class Factory(object): def create_product(self): pass class Factory1(Factory): def create_product(self): return Product1() class Factory2(Factory): def create_product(self): return Product2() if __name__ == "__main__": new_product1 = Factory1().create_product() new_product1.show() new_product2 = Factory2().create_product() new_product2.show()
1.你能夠避免建立者和具體產品之間的緊密耦合。
2.單一職責原則。 你能夠將產品建立代碼放在程序的單一位置, 從而使得代碼更容易維護。
3.開閉原則。 無需更改現有客戶端代碼, 你就能夠在程序中引入新的產品類型。
4.應用工廠方法模式須要引入許多新的子類, 代碼可能會所以變得更復雜。最好的狀況是將該模式引入建立者類的現有層次結構中。
抽象工廠模式是一種建立型設計模式, 它能建立一系列相關的對象, 而無需指定其具體類。是更多一重的工廠模式中。
抽象工廠類廠(AbstractFactory):工廠方法模式的核心類,提供建立具體產品的接口,由具體工廠類實現。
具體工廠類(Producer):繼承於抽象工廠,實現建立對應具體產品對象的方式。
抽象產品類(Factory):它是具體產品繼承的父類(基類)。
具體產品類(Factory1):具體工廠所建立的對象,就是此類。
#include <iostream> using namespace std; class AbstractProductA { public: AbstractProductA() {} virtual ~AbstractProductA() {} virtual void Show() = 0; virtual void Disp() = 0; }; class ProductA1 : public AbstractProductA { private: /* data */ public: ProductA1(){} ~ProductA1(){} void Show() { std::cout<< "productA1 show"<<std::endl; } void Disp() { std::cout<< "productA1 Disp"<<std::endl; } }; class ProductA2: public AbstractProductA { private: /* data */ public: ProductA2(){} ~ProductA2(){} void Show() { std::cout<< "productA2 show"<<std::endl; } void Disp() { std::cout<< "productA2 Disp"<<std::endl; } }; class AbstractProductB { public: AbstractProductB() {} virtual ~AbstractProductB() {} virtual void Show() = 0; virtual void Disp() = 0; }; class ProductB1 : public AbstractProductB { public: void Show() { std::cout<< "productB2 show"<<std::endl; } void Disp() { std::cout<< "productB2 Disp"<<std::endl; } }; class Factory { public: virtual AbstractProductA *CreateProductA(void) = 0; virtual AbstractProductB *CreateProductB(void) = 0; }; class Factory1 :Factory { public: AbstractProductA * CreateProductA(void) { return new ProductA1(); } AbstractProductB * CreateProductB(void) { return new ProductB1(); } }; class Factory2:Factory { public: AbstractProductA * CreateProductA(void) { return new ProductA2(); } AbstractProductB * CreateProductB(void) { return NULL; } }; int main(int argc, char **argv) { Factory2 *new_factory2 = new Factory2(); AbstractProductA *new_productA2 = new_factory2->CreateProductA(); new_productA2->Show(); Factory1 *new_factory1 = new Factory1(); AbstractProductB *new_productB1 = new_factory1->CreateProductB(); new_productB1->Show(); }
#!/usr/bin/python3 class AbstractProductA(object): def show(self): pass def disp(self): pass class ProductA1(AbstractProductA): def show(self): print("ProductA1 show") def disp(self): print("productA1 disp") class ProductA2(AbstractProductA): def show(self): print("ProductA2 show") def disp(self): print("productA2 disp") class AbstractProductB(object): def show(self): pass def disp(self): pass class ProductB1(AbstractProductB): def show(self): print("ProductB1 show") def disp(self): print("productB1 disp") class ProductB2(AbstractProductB): def show(self): print("ProductB2 show") def disp(self): print("productB2 disp") class Factory(object): def crete_product1(self): pass def crete_product2(self): pass class FactoryA(object): def crete_product1(self): return ProductA1() def crete_product2(self): return ProductA2() class FactoryB(object): def crete_product1(self): return ProductB1() def crete_product2(self): return ProductB2() if __name__ == "__main__": new_factory = FactoryA() new_product1 = new_factory.crete_product1() new_product1.show() new_product2 = new_factory.crete_product2() new_product2.disp()
1.你能夠確保同一工廠生成的產品相互匹配。能夠避免客戶端和具體產品代碼的耦合。
2.單一職責原則。 你能夠將產品生成代碼抽取到同一位置, 使得代碼易於維護。
3.開閉原則。 嚮應用程序中引入新產品變體時, 你無需修改客戶端代碼。
4.因爲採用該模式須要嚮應用中引入衆多接口和類, 代碼可能會比以前更加複雜。
這就是我分享的簡單工廠模式、工廠模式和抽象工廠模式的區別,若是你們有更好的想法和需求,也歡迎你們加我好友交流分享哈。
—END—
推薦閱讀
【3】CPU中的程序是怎麼運行起來的 必讀
【5】階段性文章總結分析
本公衆號所有原創乾貨已整理成一個目錄,回覆[ 資源 ]便可得到。