簡單工廠模式(Simple Factory Pattern)

前言

  • 學習難度:★★☆☆☆
  • 使用頻率:★★★☆☆

學會它。

開始吧java

模式名稱

中文:簡單工廠模式

English: Simple Factory Pattern

含義:簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。由於在簡單工廠模式中用於建立實例的方法是靜態(static)方法,所以簡單工廠模式又被稱爲靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。git

問題

什麼時候使用

簡單工廠模式,個人理解是:某類產品的成產線。經過設置不一樣的參數,生產出同一類別下不一樣形態的產品。

舉個例子:

手機生產線上,經過設置不一樣的參數既能夠生成小米手機,也能夠生成IPhone手機。github


存在的問題

優勢設計模式

工廠類是整個模式的關鍵.包含了必要的邏輯判斷,根據外界給定的信息,決定究竟應該建立哪一個具體類的對象.經過使用工廠類,外界能夠從直接建立具體產品對象的尷尬局面擺脫出來,僅僅須要負責「消費」對象就能夠了。而沒必要管這些對象究竟如何建立及如何組織的.明確了各自的職責和權利,有利於整個軟件體系結構的優化。bash

缺點ide

因爲工廠類集中了全部實例的建立邏輯,違反了高內聚責任分配原則,將所有建立邏輯集中到了一個工廠類中;它所能建立的類只能是事先考慮到的,若是須要添加新的類,則就須要改變工廠類了。
當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不一樣條件建立不一樣實例的需求.這種對條件的判斷和對具體產品類型的判斷交錯在一塊兒,很難避免模塊功能的蔓延,對系統的維護和擴展很是不利;
這些缺點在工廠方法模式中獲得了必定的克服。post

解決方案

先看 UML 圖:

學習

SimpleFactoryPattern UML
SimpleFactoryPattern UML



經過 Factory 類的 createProduct() 方法咱們來獲得 產品 A,產品 B 或者產品 C 的實例。

我用熟悉的 java 來實現測試

  • 需求:使用不一樣的統計圖展現數據(eg: 折線圖,餅狀圖,柱形圖)
  • 分析:各個圖形展現的數據是同樣,只是展現方式不同。且功能都是展現數據給用戶分析。擁有共同的設置數據等一些方法。
  • try code ↓

1.抽取圖表都有共同的方法 如:setData()優化

abstract class Chart {
    public void setData(Map<String, Float> data) {
        // do something same
    }

    public abstract void showChart();
}複製代碼

2.建立三個圖表的實現類

// 線形圖
public class LineChart extends Chart {
    @Override
    public void setData(Map<String, Float> data) {
        super.setData(data);
    }

    @Override
    public void showChart() {
        // do something
         System.out.println("看到這句話就僞裝看到了折線圖 ^^!");
    }
}複製代碼
// 餅狀圖
public class PieChart extends Chart {
    @Override
    public void setData(Map<String, Float> data) {
        super.setData(data);
    }
    @Override
    public void showChart() {
        // do something
    }

}複製代碼
// 柱狀圖
public class Histogram extends Chart {
    @Override
    public void setData(Map<String, Float> data) {
        super.setData(data);
    }
    @Override
    public void showChart() {
        // do something
    }
}複製代碼

3.建立咱們的圖表工廠來生成圖表

public class ChartFactory {
    public static final int FLAG_LINE_CHART = 0;
    public static final int FLAG_PIE_CHART = 1;
    public static final int FLAG_HISTOGRAM_CHART = 2;

    public static Chart getChart(int flag) {
        switch (flag) {
            case FLAG_LINE_CHART:
                return new LineChart();
            case FLAG_PIE_CHART:
                return new PieChart();
            case FLAG_HISTOGRAM_CHART:
                return new Histogram();
            default:
                return null;
        }
    }
}複製代碼

最後再來試試效果

@Test
public void SimpleFactoryTest() {
       Chart chart = ChartFactory.getChart(ChartFactory.FLAG_LINE_CHART);
       if (chart != null)
           chart.showChart();
   }複製代碼

測試結果:看到一條綠槓,並僞裝看到了 折線圖



忽然,我還想看看條形圖。那就很簡單,在新建個條形圖的類。而後修改一下工廠類ChartFactory。看似簡單,可是產品多的狀況下每次都要去修改工廠類無疑會形成維護困難。邏輯複雜。代碼臃腫,這時咱們即可以使用反射來結束這個困惑。

我這樣寫

public static Chart getChart(String flag) {
     String className = getChartProperties(flag);
     Chart chart = null;
     try {
         chart = (Chart) Class.forName(className).newInstance();
     } catch (Exception e) {
         e.printStackTrace();
     }
     return chart;
 }
// 這裏爲了不輸入 包名+類名 實在是麻煩。咱們就經過配置文件的方法來簡化這些操做
 private static String getChartProperties(String flag) {
     Properties properties = new Properties();
     try {
         properties.load(new FileInputStream("chart.properties"));
     } catch (IOException e) {
         e.printStackTrace();
     }
     if (properties != null) {
         return properties.getProperty(flag);
     }
     return null;
 }複製代碼

這是配置文件 chart.properties

# 折線圖
lineChart=com.liumeng.designpattern.smpfactory.LineChart
# 餅圖
pieChart=com.liumeng.designpattern.smpfactory.PieChart
# 柱狀圖
histogram=com.liumeng.designpattern.smpfactory.Histogram
# 條形圖
barChart=com.liumeng.designpattern.smpfactory.BarChart複製代碼

效果

你會有更好的方法,更巧妙的用法。加油。
因爲簡單工廠很容易違反高內聚責任分配原則,所以通常只在很簡單的狀況下應用。
至此,簡單工廠模式就能明白了吧。


更新中:
1. 什麼是設計模式
2. 單例模式
3. 簡單工廠模式
GitHub彙總:這裏老是最新的
看完給個star鼓勵一下

相關文章
相關標籤/搜索