設計模式(2)-物件建立型模式-Factory Method模式
1.物件建立型模式
1.2 FACTORY METHOD模式
1.2.1功能
工廠方法模式使用抽象工廠類定義一個用於建立物件(產品)的介面,讓子類(即具體工廠類)決定例項化哪一個類(即哪一個產品);
在工廠方法模式中,核心的工廠類不再負責所有的產品的建立,而是將具體建立的工作交給子類去做。這個核心類則搖身一變,成為了一個抽象工廠角色,僅負責給出具體工廠子類必須實現的介面,而不接觸哪一個產品類應當被例項化這種細節。
1.2.2結構
注:這裡把Creator改成Factory可能更直觀一點
• Creator:
— 宣告工廠方法,該方法返回一個P r o d u c t型別的物件。C r e a t o r也可以定義一個工廠方法的預設實現,它返回一個預設的C o n c r e t e P r o d u c t物件。
— 可以呼叫工廠方法以建立一個P r o d u c t物件。
• C o n c r e t e C r e a t o r
— 重定義工廠方法以返回一個C o n c r e t e P r o d u c t例項。
•P r o d u c t
— 定義工廠方法所建立的物件的介面。
•C o n c r e t e P r o d u c t
— 實現Pr o d u c t介面。
1.2.3優缺點
工廠方法模式的優點如下:
(1)在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被例項化這一細節,使用者只需要關心所需產品對應的工廠,無需關心建立細節,甚至無需知道具體產品類的類名。
(2)基於工廠角色和產品角色的多型性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品物件,而如何建立這個物件的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多型工廠模式,正是因為所有的具體工廠類都具有同一抽象父類。
(3)使用工廠方法模式的另一個優點是在系統中加入新產品時,無需修改抽象工廠和抽象產品提供的介面,無需修改客戶端,也無需修改其他的具體工廠和具體產品,而只要新增一個具體工廠和具體產品就可以了,這樣,系統的可擴充套件性也就變得非常好,完全符合“開閉原則”。
工廠方法模式的缺點如下:
(1)在新增新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和執行,會給系統帶來一些額外的開銷。
(2)由於考慮到系統的可擴充套件性,需要引入抽象層,在客戶端程式碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。
1.2.4 例子-C++
//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class Product
{
public:
virtual ~Product() = 0;
protected:
Product();
private:
};
class ConcreteProduct :public Product
{
public:
~ConcreteProduct();
ConcreteProduct();
protected:
private:
};
#endif //~_PRODUCT_H_
//Product.cpp
#include"Product.h"
#include<iostream>
using namespace std;
Product::Product()
{
}
Product::~Product()
{
}
ConcreteProduct::ConcreteProduct()
{
cout << "ConcreteProduct...." << endl;
}
ConcreteProduct::~ConcreteProduct()
{
}
//Factory.h
#ifndef _FACTORY_H_
#define _FACTORY_H_
class Product;
class Factory
{
public:
virtual ~Factory() = 0;
virtual Product*CreateProduct() = 0;
protected:
Factory();
private:
};
class ConcreteFactory :public Factory
{
public:
~ConcreteFactory();
ConcreteFactory();
Product* CreateProduct();
protected:
private:
};
#endif //~_FACTORY_H_
//Factory.cpp
#include "Factory.h"
#include "Product.h"
#include <iostream>
using namespace std;
Factory::Factory()
{
}
Factory::~Factory()
{
}
ConcreteFactory::ConcreteFactory()
{
cout << "ConcreteFactory....." << endl;
}
ConcreteFactory::~ConcreteFactory()
{
}
Product* ConcreteFactory::CreateProduct()
{
return new ConcreteProduct();
}
//main.cpp
#include"Factory.h"
#include"Product.h"
#include<iostream>
using namespace std;
int main(int argc, char*argv[])
{
Factory *fac = new ConcreteFactory();
Product * p = fac->CreateProduct();
return 0;
}
1.2.5 例子-JAVA
1. //抽象產品
2. PenCore.java
3. public abstract class PenCore{
4. String color;
5. public abstract void writeWord(String s);
6. }
7. //具體產品
8. RedPenCore.java
9. public class RedPenCore extends PenCore {
10. RedPenCore() {
11. color = "紅色";
12. }
13. public void writeWord(String s) {
14. System.out.println("寫出" + color + "的字" + s);
15. }
16.}
17.BluePenCore.java
18.public class BluePenCore extends PenCore {
19. BluePenCore() {
20. color = "藍色";
21. }
22. public void writeWord(String s) {
23. System.out.println("寫出" + color + "的字" + s);
24. }
25.}
26.BlackPenCore.java
27.public class BlackPenCore extends PenCore {
28. BlackPenCore() {
29. color = "黑色";
30. }
31. public void writeWord(String s) {
32. System.out.println("寫出" + color + "的字" + s);
33. }
34.}
1. //構造者
2. BallPen.java
3. public abstract class BallPen {
4. BallPen(){
5. System.out.println("生產一隻裝有"+getPenCore().color+"筆芯的圓珠筆");
6. }
7. public abstract PenCore getPenCore();
8. }
9.
10.//具體構造者
11.RedBallPen.java
12.public class RedBallPen extends BallPen {
13. public PenCore getPenCore() {
14. return new RedPenCore();
15. }
16.}
17.BlueBallPen.java
18.public class BlueBallPen extends BallPen {
19. public PenCore getPenCore() {
20. return new BluePenCore();
21. }
22.}
23.
24.BlackBallPen.java
25.public class BlackBallPen extends BallPen {
26. public PenCore getPenCore() {
27. return new BlackPenCore();
28. }
29.}
30.
public class TestMain {
/**
* @param args
*/
public static void main(String[] args){
// TODO Auto-generatedmethod stub
BallPenballPen=new BlackBallPen();
PenCorepenCore=ballPen.getPenCore();
penCore.writeWord("工廠方法模式");
return;
}
}