前言
- 學習難度:★★☆☆☆
- 使用頻率:★★★☆☆
學會它。
開始吧
模式名稱
中文:簡單工廠模式
English: Simple Factory Pattern
含義:簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。因為在簡單工廠模式中用於建立例項的方法是靜態(static)方法,因此簡單工廠模式又被稱為靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。
問題
何時使用
簡單工廠模式,我的理解是:某類產品的成產線。通過設定不同的引數,生產出同一類別下不同形態的產品。
舉個例子:
手機生產線上,通過設定不同的引數既可以生成小米手機,也可以生成IPhone手機。
存在的問題
優點
工廠類是整個模式的關鍵.包含了必要的邏輯判斷,根據外界給定的資訊,決定究竟應該建立哪個具體類的物件.通過使用工廠類,外界可以從直接建立具體產品物件的尷尬局面擺脫出來,僅僅需要負責“消費”物件就可以了。而不必管這些物件究竟如何建立及如何組織的.明確了各自的職責和權利,有利於整個軟體體系結構的優化。
缺點
由於工廠類集中了所有例項的建立邏輯,違反了高內聚責任分配原則,將全部建立邏輯集中到了一個工廠類中;它所能建立的類只能是事先考慮到的,如果需要新增新的類,則就需要改變工廠類了。
當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件建立不同例項的需求.這種對條件的判斷和對具體產品型別的判斷交錯在一起,很難避免模組功能的蔓延,對系統的維護和擴充套件非常不利;
這些缺點在工廠方法模式中得到了一定的克服。
解決方案
先看 UML 圖:
![SimpleFactoryPattern UML](https://i.iter01.com/images/61554b2334a3c9d9a3b52d5fccaddea016269e4e3745823bc583ed883a23b594.png)
通過
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鼓勵一下
![](https://i.iter01.com/images/5bd1744295f9485d23a85e1680d4234f687a4345eb75b72fbe0361623fb705f1.jpg)