工廠模式是最經常使用的一種建立型模式,一般所說的工廠模式通常是指工廠方法模式。本篇是是工廠方法模式的「小弟」,咱們能夠將其理解爲工廠方法模式的預備知識,它不屬於GoF 23種設計模式,但在軟件開發中卻也應用地比較頻繁。此外,工廠方法模式還有一位「大哥」—抽象工廠模式,會在後面進行介紹。程序員
簡單工廠模式(Simple Factory) | 學習難度:★★☆☆☆ | 使用頻率:★★★☆☆ |
M公司想要基於C#語言開發一套圖表庫,該圖表庫能夠爲應用系統提供各類不一樣外觀的圖標,例如柱狀圖、餅狀圖或折線圖等。M公司圖表庫設計開發人員但願爲應用系統開發人員提供一套靈活易用的圖表庫,並且能夠較爲方便地對圖表庫進行擴展,以便於在未來增長一些新類型的圖表。設計模式
M公司的程序員提出了一個初始設計方案,將全部圖表的實現代碼封裝在一個Chart類中,其框架代碼以下所示:app
public class Chart { private string type; // 圖表類型 public Chart(object[][] data, string type) { this.type = type; if (this.type.Equals("histogram", StringComparison.OrdinalIgnoreCase)) { // 初始化柱狀圖 } else if (this.type.Equals("pie", StringComparison.OrdinalIgnoreCase)) { // 初始化餅狀圖 } else if (this.type.Equals("line", StringComparison.OrdinalIgnoreCase)) { // 初始化折線圖 } } public void Display() { if (this.type.Equals("histogram", StringComparison.OrdinalIgnoreCase)) { // 顯示柱狀圖 } else if (this.type.Equals("pie", StringComparison.OrdinalIgnoreCase)) { // 顯示餅狀圖 } else if (this.type.Equals("line", StringComparison.OrdinalIgnoreCase)) { // 顯示折線圖 } } }
客戶端代碼經過調用Chart類的構造函數來建立圖表對象,根據參數type的不一樣能夠獲得不一樣類型的圖標,而後再調用Display()方法來顯示相應的圖表。框架
可是,不難看出,Chart類是一個巨大的類,存在不少問題:函數
簡單工廠模式並不屬於GoF 23種經典設計模式,但一般將它做爲學習其餘工廠模式的基礎。學習
簡單工廠(Simple Factory)模式:定義一個工廠類,它能夠根據參數的不一樣返回不一樣類的實例,被建立的實例一般都具備共同的父類。由於在簡單工廠模式中用於建立實例的方法是靜態(static)方法,所以簡單工廠模式又被稱爲靜態工廠方法模式,它屬於建立型模式。this
簡單工廠模式的要點在於:當你須要什麼,只須要傳入一個正確的參數,就能夠獲取你所需的對象,而無須知道其建立細節。spa
簡單工廠模式包含3個角色:設計
在簡單工廠模式中,客戶端經過工廠類來建立一個產品類的實例,而無須直接使用new關鍵字來建立對象。(能夠看出,它是工廠模式家族中最簡單的一員)code
爲了將Chart類的職責分離,同時將Chart對象的建立和使用分離,M公司開發人員決定使用簡單工廠模式對圖表庫進行重構,重構後的結構圖以下所示:
(1)抽象產品角色:IChartable接口
public interface IChartable { void Display(); }
(2)具體產品角色:各類圖表類型
public class HistogramChart : IChartable { public HistogramChart() { Console.WriteLine("建立柱狀圖..."); } public void Display() { Console.WriteLine("顯示柱狀圖..."); } } public class LineChart : IChartable { public LineChart() { Console.WriteLine("建立折線圖..."); } public void Display() { Console.WriteLine("顯示折線圖..."); } } public class PieChart : IChartable { public PieChart() { Console.WriteLine("建立餅狀圖..."); } public void Display() { Console.WriteLine("顯示餅狀圖..."); } }
(3)工廠角色:ChartFactory
public class ChartFactory { public static IChartable GetChart(string type) { IChartable chart = null; if (type.Equals("histogram", StringComparison.OrdinalIgnoreCase)) { chart = new HistogramChart(); Console.WriteLine("初始化設置柱狀圖..."); } else if (type.Equals("pie", StringComparison.OrdinalIgnoreCase)) { chart = new PieChart(); Console.WriteLine("初始化設置餅狀圖..."); } else if (type.Equals("line", StringComparison.OrdinalIgnoreCase)) { chart = new PieChart(); Console.WriteLine("初始化設置折線圖..."); } return chart; } }
(4)客戶端調用:
public static void Main() { IChartable chart = ChartFactory.GetChart("histogram"); if (chart != null) { chart.Display(); } chart = ChartFactory.GetChart("pie"); if (chart != null) { chart.Display(); } }
運行結果以下:
在客戶端代碼中,使用工廠類的靜態方法來建立具體產品對象,若是須要更換產品,只須要修改靜態工廠方法中的參數便可。例如:將柱狀圖改成餅狀圖,只須要將代碼:
IChartable chart = ChartFactory.GetChart("histogram");
改成:
IChartable chart = ChartFactory.GetChart("pie");
M公司開發人員發如今建立具體Chart對象時,每次更換一個Chart對象都須要修改客戶端中靜態工廠方法的參數,客戶端代碼須要從新編譯,這對於客戶端而言,是違反了開閉原則的。因而,開發人員但願有一種方法可以在不修改客戶端代碼地前提下更換具體產品對象。
所以,他們考慮使用配置文件(XML)來實現:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <add key="charttype" value="histogram"/> </appSettings> </configuration>
客戶端所以改成:
public static void Main() { string type = AppConfigHelper.GetChartType(); // 讀取配置文件中的charttype if (string.IsNullOrEmpty(type)) { return; } IChartable chart = ChartFactory.GetChart(type); if (chart != null) { chart.Display(); } }
運行結果以下:
劉偉,《設計模式的藝術—軟件開發人員內功修煉之道》