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;
}
}