標籤:class blog http com 使用 檔案
一、概述
原廠模式具體包括了簡單工廠、Factory 方法、抽象工廠,它們是按照從簡單到複雜的順序排列的,屬於設計模式中的建立型,其中簡單工廠並不屬於GOF的23中模式。
但是它是理解其它的原廠模式的一個很好的基礎,所以很多人在講述設計模式的時候會提到簡單原廠模式。
建立型模式關注的是對象的建立,建立型模式將建立對象的過程進行了抽象,也可以理解為將建立對象的過程進行了封裝,作為客戶程式僅僅需要去使用對象,而不再關心建立對象過程中的邏輯。
優點:
1)解決了代碼中大量的new的問題,把new對象的操作集中封裝到工廠類裡面,這樣一來,用Factory 方法在一個類的內部建立對象通常比直接建立對象更靈活
缺點:
1)由於是簡單的封裝,所以此模式下對修改不封閉,新增產品時需要修改工廠類,違犯了開閉法則(OCP)。
因為如果直接在工廠類的內部生產(new)所有的產品,當新增產品時,要去修改工廠類,封裝性不好。
舉例說明:
簡單工廠就是把某一類的產品做了規劃,使其形成一個產品集合。但這些產品類不直接對外開放,而是通過它們的基類介面供外界調用,
這就如同一個鞋廠,我們提貨當然不能直接到生產部提貨的, 你要知道生產部流水線很多的,他們只知道自己線上的型號,其它線上的型號可是一問三不知,何況作為一個外來人員,你要申請才能去參觀哦。
所以你就不要折騰了,這個鞋廠已經安排了銷售部負責對外供貨。如果我們需要什麼型號的皮鞋,直接找銷售部,銷售部會幫你做好一切安排。
現在很多代碼都是沒用使用工廠類,而是直接調用Prodcut類直接使用產品的,這就造成new來new去漫天飛,現在有了簡單原廠模式,規劃好產品,管理好產品,一切都在向良性方向發展。
簡而言之:
簡單工廠兩個類簇:一個類簇是Product,重在實現產品;一個類簇是Factory,重在是建立及管理產品。原則上,外界對產品的操作只能通過Factory,而不能直接對Product,這樣保護了Product的秘密性。
Product類負責完成各種各樣的產品,對外面只提供有限的介面;它有2層結構:產品虛基類-產品子類
Factory類負責建立產品,它有1層結構:簡單工廠類
二,類圖:
三,代碼:
SimpleFactory.h
#pragma once//工廠類依賴於產品類,因為沒有產品的工廠不能稱之為工廠,所以有://工廠類---(調用)--->產品類#include "IProduct.h" //下面的標頭檔其實應該放到cpp檔案裡面,之所以放在這裡是為了更好詮釋簡單原廠模式(將它們一齊集中到h檔案說明)#include "ConcreteProductA.h" #include "ConcreteProductB.h"//工廠類:外層返回產品基類,內層生產(建立,new)具體的產品。//這就像是工廠向外界供貨一樣,客戶需要什麼產品,一個電話打到生產部,讓生產部直接拿產品過來。即:一步(new)成型,並不會關注產品的製作過程。class CSimpleFactory{public:CSimpleFactory() {};~CSimpleFactory() {};public:IProduct * CreateProduct(int nProductType);IProduct *CreateProductA();IProduct *CreateProductB();};
SimpleFactory.cpp
#include"SimpleFactory.h"IProduct *CSimpleFactory::CreateProduct(int nProductType){IProduct *ptr = 0;switch (nProductType){case 0:ptr = new CConcreteProductA();break;case 1:ptr = new CConcreteProductB();break;default:ptr = new CConcreteProductA();}return ptr;}IProduct *CSimpleFactory::CreateProductA(){cout<<__FUNCTION__<<endl;return new CConcreteProductA();}IProduct *CSimpleFactory::CreateProductB(){cout<<__FUNCTION__<<endl;return new CConcreteProductB();}
IProduct.h
#pragma once#include <stdio.h>#include <iostream>using namespace std;//這是一個產品虛基類:它的任務就是用來定型(抽象)所需求產品,抽象出它們的公用屬性,然後讓它的衍生類別一門心思地去完成自身的功能。//所以它並不依賴於任何業務相關的標頭檔,但有可能會依賴系統標頭檔,比如你使用了string,必須要包含string標頭檔//這個產品基類之所以存在是因為我們要為我們生產的產品抽象出了它們的公用屬性,而這個公用屬性是對外開放,供外部(比如說用戶端程式)調用的。//外部調用時將以多態性進行操作,不會接觸到產品內部的細節,這樣就保證的產品的封閉性。class IProduct{protected:IProduct();public:virtual ~IProduct();public:virtual void Function() = 0;};
IProduct.cpp
#include "IProduct.h"IProduct::IProduct(void){}IProduct::~IProduct(void){}
ConcreteProductA.h
#pragma once#include "IProduct.h" //CConcreteProductA(衍生類別) ----|> IProduct(基類)//實現產品的具體細節:基於產品功能需求(基類介面),具體化出功能A產品class CConcreteProductA :public IProduct{public:CConcreteProductA();virtual ~CConcreteProductA();virtual void Function();};
ConcreteProductA.cpp
#include "ConcreteProductA.h"CConcreteProductA::CConcreteProductA(void) {cout<<__FUNCTION__<<endl;}CConcreteProductA::~CConcreteProductA(void) {cout<<__FUNCTION__<<endl;}void CConcreteProductA::Function() {cout<<__FUNCTION__<<endl;}
ConcreteProductB.h
#pragma once#include "IProduct.h" //CConcreteProductA(衍生類別) ----|> CProduct(基類)//實現產品的具體細節:基於產品功能需求(基類介面),具體化出功能B產品class CConcreteProductB :public IProduct{public:CConcreteProductB(void);virtual ~CConcreteProductB(void);virtual void Function();};
ConcreteProductB.cpp
#include "ConcreteProductB.h"CConcreteProductB::CConcreteProductB(void) {cout<<__FUNCTION__<<endl;}CConcreteProductB::~CConcreteProductB(void) {cout<<__FUNCTION__<<endl;}void CConcreteProductB::Function() {cout<<__FUNCTION__<<endl;}
main.cpp
#include "SimpleFactory.h"#include <stdio.h>int main(){CSimpleFactory fac;IProduct *pProduct = fac.CreateProductA();pProduct->Function();delete pProduct;pProduct = NULL;pProduct = fac.CreateProductB();pProduct->Function();delete pProduct;pProduct = NULL;return 0;}
四,運行結果:
CSimpleFactory::CreateProductA
CConcreteProductA::CConcreteProductA
CConcreteProductA::Function
CConcreteProductA::~CConcreteProductA
CSimpleFactory::CreateProductB
CConcreteProductB::CConcreteProductB
CConcreteProductB::Function
CConcreteProductB::~CConcreteProductB
請按任意鍵繼續. . .