工廠方法模式(FactoryMethod)
在現(xiàn)實生活中社會分工越來越細,越來越專業(yè)化。各種產(chǎn)品有專門的工廠生產(chǎn),徹底告別了自給自足的小農(nóng)經(jīng)濟時代,這大大縮短了產(chǎn)品的生產(chǎn)周期,提高了生產(chǎn)效率。同樣,在軟件開發(fā)中能否做到軟件對象的生產(chǎn)和使用相分離呢?能否在滿足“開閉原則”的前提下,客戶隨意增刪或改變對軟件相關(guān)對象的使用呢?這就是本節(jié)要討論的問題。
工廠方法模式的定義與特點
工廠方法(FactoryMethod)模式的定義:
定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將產(chǎn)品對象的實際創(chuàng)建工作推遲到具體子工廠類當中。這滿足創(chuàng)建型模式中所要求的“創(chuàng)建與使用相分離”的特點。-
工廠方法模式的優(yōu)點:
- 用戶只需要知道具體工廠的名稱就可得到所要的產(chǎn)品,無須知道產(chǎn)品的具體創(chuàng)建過程。
- 在系統(tǒng)增加新的產(chǎn)品時只需要添加具體產(chǎn)品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;
工廠方法模式的缺點:
每增加一個產(chǎn)品就要增加一個具體產(chǎn)品類和一個對應的具體工廠類,這增加了系統(tǒng)的復雜度。
模式的結(jié)構(gòu)與實現(xiàn)
工廠方法模式由抽象工廠、具體工廠、抽象產(chǎn)品和具體產(chǎn)品等4個要素構(gòu)成。本節(jié)來分析其基本結(jié)構(gòu)和實現(xiàn)方法。
1. 模式的結(jié)構(gòu)
工廠方法模式的主要角色如下。
- 抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口,調(diào)用者通過它訪問具體工廠的工廠方法 newProduct() 來創(chuàng)建產(chǎn)品。
- 具體工廠(ConcreteFactory):主要是實現(xiàn)抽象工廠中的抽象方法,完成具體產(chǎn)品的創(chuàng)建。
- 抽象產(chǎn)品(Product):定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能
- 具體產(chǎn)品(ConcreteProduct):實現(xiàn)了抽象產(chǎn)品角色所定義的接口,由具體工廠來創(chuàng)建,它同具體工廠之間一一對應。
工廠方法模式的結(jié)構(gòu)圖
2. 模式的實現(xiàn)
package FactoryMethod;
public class AbstractFactoryTest
{
public static void main(String[] args)
{
try
{
Product a;
AbstractFactory af;
af=(AbstractFactory) ReadXML1.getObject();
a=af.newProduct();
a.show();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
}
}
//抽象產(chǎn)品:提供了產(chǎn)品的接口
interface Product
{
public void show();
}
//具體產(chǎn)品1:實現(xiàn)抽象產(chǎn)品中的抽象方法
class ConcreteProduct1 implements Product
{
public void show()
{
System.out.println("具體產(chǎn)品1顯示...");
}
}
//具體產(chǎn)品2:實現(xiàn)抽象產(chǎn)品中的抽象方法
class ConcreteProduct2 implements Product
{
public void show()
{
System.out.println("具體產(chǎn)品2顯示...");
}
}
//抽象工廠:提供了廠品的生成方法
interface AbstractFactory
{
public Product newProduct();
}
//具體工廠1:實現(xiàn)了廠品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具體工廠1生成-->具體產(chǎn)品1...");
return new ConcreteProduct1();
}
}
//具體工廠2:實現(xiàn)了廠品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
public Product newProduct()
{
System.out.println("具體工廠2生成-->具體產(chǎn)品2...");
return new ConcreteProduct2();
}
}
工廠方法模式的實例
我們將創(chuàng)建一個 Shape 接口和實現(xiàn) Shape 接口的實體類。下一步是定義工廠類 ShapeFactory。
FactoryPatternDemo,我們的演示類使用 ShapeFactory 來獲取 Shape 對象。它將向 ShapeFactory 傳遞信息(CIRCLE / RECTANGLE / SQUARE),以便獲取它所需對象的類型。

1. 創(chuàng)建一個接口: Shape.java
public interface Shape {
void draw();
}
2. 創(chuàng)建實現(xiàn)接口的實體類。Rectangle.java、Square.java、Circle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Inside Rectangle::draw() method.");
}
}
public class Square implements Shape {
@Override
public void draw() {
System.out.println("Inside Square::draw() method.");
}
}
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Inside Circle::draw() method.");
}
}
3. 創(chuàng)建一個工廠,生成基于給定信息的實體類的對象。ShapeFactory.java
public class ShapeFactory {
//使用 getShape 方法獲取形狀類型的對象
public Shape getShape(String shapeType){
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
} else if(shapeType.equalsIgnoreCase("SQUARE")){
return new Square();
}
return null;
}
}
4. 使用該工廠,通過傳遞類型信息來獲取實體類的對象。FactoryPatternDemo.java
public class FactoryPatternDemo {
public static void main(String[] args) {
ShapeFactory shapeFactory = new ShapeFactory();
//獲取 Circle 的對象,并調(diào)用它的 draw 方法
Shape shape1 = shapeFactory.getShape("CIRCLE");
//調(diào)用 Circle 的 draw 方法
shape1.draw();
//獲取 Rectangle 的對象,并調(diào)用它的 draw 方法
Shape shape2 = shapeFactory.getShape("RECTANGLE");
//調(diào)用 Rectangle 的 draw 方法
shape2.draw();
//獲取 Square 的對象,并調(diào)用它的 draw 方法
Shape shape3 = shapeFactory.getShape("SQUARE");
//調(diào)用 Square 的 draw 方法
shape3.draw();
}
}
執(zhí)行程序,輸出結(jié)果:
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
工廠方法模式的應用場景
工廠方法模式通常適用于以下場景。
- 客戶只知道創(chuàng)建產(chǎn)品的工廠名,而不知道具體的產(chǎn)品名。如 TCL 電視工廠、海信電視工廠等。
- 創(chuàng)建對象的任務由多個具體子工廠中的某一個完成,而抽象工廠只提供創(chuàng)建產(chǎn)品的接口。
- 客戶不關(guān)心創(chuàng)建產(chǎn)品的細節(jié),只關(guān)心產(chǎn)品的品牌。
工廠方法模式的擴展
當需要生成的產(chǎn)品不多且不會增加,一個具體工廠類就可以完成任務時,可刪除抽象工廠類。這時工廠方法模式將退化到簡單工廠模式,其結(jié)構(gòu)圖如下圖所示。

