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

工廠方法模式(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)點:

    1. 用戶只需要知道具體工廠的名稱就可得到所要的產(chǎn)品,無須知道產(chǎn)品的具體創(chuàng)建過程。
    2. 在系統(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)
工廠方法模式的主要角色如下。

  1. 抽象工廠(Abstract Factory):提供了創(chuàng)建產(chǎn)品的接口,調(diào)用者通過它訪問具體工廠的工廠方法 newProduct() 來創(chuàng)建產(chǎn)品。
  2. 具體工廠(ConcreteFactory):主要是實現(xiàn)抽象工廠中的抽象方法,完成具體產(chǎn)品的創(chuàng)建。
  3. 抽象產(chǎn)品(Product):定義了產(chǎn)品的規(guī)范,描述了產(chǎn)品的主要特性和功能
  4. 具體產(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),以便獲取它所需對象的類型。

image

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)圖如下圖所示。


簡單工廠模式的結(jié)構(gòu)圖
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

  • 簡單工廠模式雖然簡單,但存在一個很嚴重的問題。當系統(tǒng)中需要引入新產(chǎn)品時,由于靜態(tài)工廠方法通過所傳入?yún)?shù)的不同來創(chuàng)建...
    justCode_閱讀 1,308評論 1 9
  • 工廠模式是我們最常用的實例化對象模式了,是用工廠方法代替new操作的一種模式。通常我們所說的工廠模式是指工廠方法模...
    zfylin閱讀 1,403評論 0 7
  • 創(chuàng)建型模式 工廠模式 工廠模式(Factory Pattern)是 Java 中最常用的設(shè)計模式之一。這種類型的設(shè)...
    隔墻送來秋千影閱讀 2,819評論 0 11
  • 走吧 別離是新的開始 一切悄無聲息 為你擦去眼角的淚滴 這世界哪有不散的宴席 該來的終將會來 該去的終將過去 走吧...
    沽栗閱讀 235評論 0 3
  • 就如人生的意義就是活著本身一樣,哪有那么多的意義,本來就是無聊人的YY!
    暗黑大圣歸來閱讀 205評論 0 0

友情鏈接更多精彩內(nèi)容