創建型模式篇(工廠模式Factory Pattern)
阿新 • • 發佈:2018-03-16
sel case create png image eventlog ole 擁有 其他
一、工廠模式(Factory Pattern)
1、定義: 在軟件系統,經常面臨著“某個對象”的創建工作,由於需求的變化,這個對象的具體實現經常面臨著劇烈的變化,但是它卻擁有比較穩定的接口。提供一種封裝機制來隔離這個對象的變化,從而保持系統中其他依賴這個變化對象的對象,就要用到工廠模式。
2、目的:定義一個用戶創建對象的接口,讓子類決定實例化哪一個類,FactoryMethod使一個類的實例化延遲到它的子類。
3、結構圖:
工廠模式:定義一個用於創建對象的接口,但是讓子類決定實例化哪個類。也就是說在工廠模式中,核心的工廠類不在負責所有產品的創建,而是將具體創建工作交給它的子類去做。這個核心類僅僅負責給出具體工廠必須實現的接口,而不用接觸哪一個產品類被實例化這種細節。
現實工作中的例子:
//設計日誌記錄類Log,支持記錄的方法有FileLog和EventLog兩種記錄類型。 //不用設計模式來實現: public class Log { public void WriteEvent() { Console.WriteLine("EventLog Success!"); } public void WriteFile() { Console.WriteLine("FileLog Success!"); } public void Write(string LogType) {switch(LogType.ToLower()) { case "event": WriteEvent(); break; case "file": WriteFile(); break; default: break; } } }//這樣程序結構顯然不符合我們要求,加入要增加一種新的日誌類型DataBaseLog,那麽就要修改Log類,重新加入 //switch語句不斷在變化,這就引起了整個應用程序的不穩定,EventLog和FileLog是兩種完全不同的記錄方式 //他們之前不存在必然的聯系,應該把他們分別作為單獨的對象來處理對待
使用工廠模式來實現:
思想是為EventLog和FileLog抽象出一個共同的父類,結構圖如下:
//首先抽象一個父類Log public abstact class Log { public abstract void Write(); } //讓EventLog和FileLog去繼承父類,重寫父類裏的方法 //EventLog類 public class EventLog:Log { public override void Write() { Conosole.WriteLine("EventLog Write Success!"); } } //FileLog類 public class FileLog:Log { public override void Write() { Console.WriteLine("FileLog Write Success!"); } } //現在再有一個新的日誌記錄方式DataBaseLog時候,只需要增加一個DataBaseLog子類去繼承父類就可以 //不用去修改EventLog和FileLog類,滿足了類之間的層次關系,又很好的符合面向對象設計中的 //單一職責原則,每一個類都只負責一件具體的事情。 //但是我們並不確定客戶程序去調用哪一種日誌記錄方式 //也許會用到下面的語句: EventLog eventLog=new EventLog(); eventLog.Write(); //當日誌記錄方式從EventLog變成FileLog時候,我們就要修改程序中上面的創建對象語句。 //這樣的工作量可想而知,此時就需要解耦具體的日誌記錄方式,就可以引入工廠模式了 //每一個日誌記錄的對象就是工廠所生成的產品,既然有兩種記錄方式,那就需要兩個不同的工廠去生產。
因此聲明兩個不同類型的工廠類:EventFactory類和FileFactory類
//EventFactory類 public class EventFactory { public EventLog Create() { return new EventLog(); } } //FileFactory類 public class FileFactory { public FileFactory Create() { return new FileLog(); } }
這兩個工廠和具體的產品之間是平行的結構,並且一一對應,我們在他們兩個基礎上抽象出一個公用的接口:
//LogFactory類 public abstract class LogFactory { public abstract Log Create(); } //EventFactory類 public class EventFactory:LogFactory { public override EventLog Create() { return new EventLog(); } } //FileFactory類 public class FileFactory:LogFactory { public override FileFactory Create() { return new FileLog(); } } //這樣通過工廠模式,把上面對象創建工作封裝在了工廠中,達到了具體應用程序 //和具體日誌記錄方式對象之間的解耦 //客戶端調用代碼 publc class Test { public static void Main(string[] args) { LogFactory factory=new EventFactory(); Log log=factory.Create(); log.Write(); } }
在應用程序中,Log對象創建是頻繁的,要是換成另一種日誌記錄方式,只需要修改為:
LogFactory factory=new FileFactory()
其他任何地方都不需要修改,我們也可以說個.net的特性,避免這種不必要的修改,利用.net的反射機制來進行實現,所以就要用到配置文件了,如果我們想用哪一種日誌記錄方式,就在相應的配置文件中設置如下:
<appSettings> <add key="factoryName" value="EventFactory"></add? </appSettings>
然後客戶端代碼可以這樣寫:
//客戶端調用代碼 publc class Test { public static void Main(string[] args) { string strFactoryName=ConfigurationSettings.AppSettings["factoryName"];//引入配置文件 LogFactory factory; factory=(LogFactory)Assembly.Load("FactoryMethod").CreateInstance("FactoryMethod"+strFactoryName); Log log=factory.Create(); log.Write(); } }
創建型模式篇(工廠模式Factory Pattern)