天天看點

設計模式--工廠方法模式(FactoryMethod)工廠方法模式(FactoryMethod)

工廠方法模式(FactoryMethod)

在現實生活中社會分工越來越細,越來越專業化。各種産品有專門的工廠生産,徹底告别了自給自足的小農經濟時代,這大大縮短了産品的生産周期,提高了生産效率。同樣,在軟體開發中能否做到軟體對象的生産和使用相分離呢?能否在滿足“開閉原則”的前提下,客戶随意增删或改變對軟體相關對象的使用呢?這就是本節要讨論的問題。

工廠方法模式的定義與特點

  • 工廠方法(FactoryMethod)模式的定義:

    定義一個建立産品對象的工廠接口,将産品對象的實際建立工作推遲到具體子工廠類當中。這滿足建立型模式中所要求的“建立與使用相分離”的特點。

  • 工廠方法模式的優點:

    1.使用者隻需要知道具體工廠的名稱就可得到所要的産品,無須知道産品的具體建立過程。

    2.在系統增加新的産品時隻需要添加具體産品類和對應的具體工廠類,無須對原工廠進行任何修改,滿足開閉原則;

  • 工廠方法模式的缺點:

    每增加一個産品就要增加一個具體産品類和一個對應的具體工廠類,這增加了系統的複雜度。

模式的結構與實作

工廠方法模式由抽象工廠、具體工廠、抽象産品和具體産品等4個要素構成。本節來分析其基本結構和實作方法。

1. 模式的結構

工廠方法模式的主要角色如下。

  1. 抽象工廠(Abstract Factory):提供了建立産品的接口,調用者通過它通路具體工廠的工廠方法 newProduct() 來建立産品。
  2. 具體工廠(ConcreteFactory):主要是實作抽象工廠中的抽象方法,完成具體産品的建立。
  3. 抽象産品(Product):定義了産品的規範,描述了産品的主要特性和功能
  4. 具體産品(ConcreteProduct):實作了抽象産品角色所定義的接口,由具體工廠來建立,它同具體工廠之間一一對應。
    設計模式--工廠方法模式(FactoryMethod)工廠方法模式(FactoryMethod)
    2. 模式的實作
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());
        }
    }
}
//抽象産品:提供了産品的接口
interface Product
{
    public void show();
}
//具體産品1:實作抽象産品中的抽象方法
class ConcreteProduct1 implements Product
{
    public void show()
    {
        System.out.println("具體産品1顯示...");
    }
}
//具體産品2:實作抽象産品中的抽象方法
class ConcreteProduct2 implements Product
{
    public void show()
    {
        System.out.println("具體産品2顯示...");
    }
}
//抽象工廠:提供了廠品的生成方法
interface AbstractFactory
{
    public Product newProduct();
}
//具體工廠1:實作了廠品的生成方法
class ConcreteFactory1 implements AbstractFactory
{
    public Product newProduct()
    {
        System.out.println("具體工廠1生成-->具體産品1...");
        return new ConcreteProduct1();
    }
}
//具體工廠2:實作了廠品的生成方法
class ConcreteFactory2 implements AbstractFactory
{
    public Product newProduct()
    {
        System.out.println("具體工廠2生成-->具體産品2...");
        return new ConcreteProduct2();
    }
}
           

工廠方法模式的執行個體

我們将建立一個 Shape 接口和實作 Shape 接口的實體類。下一步是定義工廠類 ShapeFactory。

FactoryPatternDemo,我們的示範類使用 ShapeFactory 來擷取 Shape 對象。它将向 ShapeFactory 傳遞資訊(CIRCLE / RECTANGLE / SQUARE),以便擷取它所需對象的類型。

設計模式--工廠方法模式(FactoryMethod)工廠方法模式(FactoryMethod)

1. 建立一個接口: Shape.java

public interface Shape {
   void draw();
}
           

2. 建立實作接口的實體類。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. 建立一個工廠,生成基于給定資訊的實體類的對象。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 的對象,并調用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //調用 Circle 的 draw 方法
      shape1.draw();
 
      //擷取 Rectangle 的對象,并調用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //調用 Rectangle 的 draw 方法
      shape2.draw();
 
      //擷取 Square 的對象,并調用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //調用 Square 的 draw 方法
      shape3.draw();
   }
}
           

執行程式,輸出結果:

Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
           

工廠方法模式的應用場景

工廠方法模式通常适用于以下場景。

  • 客戶隻知道建立産品的工廠名,而不知道具體的産品名。如 TCL 電視工廠、海信電視工廠等。
  • 建立對象的任務由多個具體子工廠中的某一個完成,而抽象工廠隻提供建立産品的接口。
  • 客戶不關心建立産品的細節,隻關心産品的品牌。

工廠方法模式的擴充

當需要生成的産品不多且不會增加,一個具體工廠類就可以完成任務時,可删除抽象工廠類。這時工廠方法模式将退化到簡單工廠模式,其結構圖如下圖所示。

設計模式--工廠方法模式(FactoryMethod)工廠方法模式(FactoryMethod)

繼續閱讀