說說設計模(mo)式~工廠方法模(mo)式(Factory Method)
在簡單工廠的講解中,出現了(le)很多(duo)問題(ti),我們對象(xiang)統一(yi)行為抽(chou)象(xiang)出一(yi)個接口(kou)(或者抽(chou)象(xiang)類)之后,再根(gen)據你(ni)傳入的類型進行創建實(shi)(shi)例,這只適(shi)合于(yu)你(ni)有(you)固(gu)定行為的場(chang)合,當(dang)你(ni)要實(shi)(shi)現接口(kou)的類型處(chu)于(yu)不定數(shu)時(shi),則不適(shi)合使用簡單工(gong)廠模(mo)式,而應該用工(gong)廠方法了(le)。
適用場合:
子類(lei)有統(tong)一的操(cao)作行為(wei)
子(zi)類的數量不固定,隨(sui)時(shi)可能有新的功能子(zi)類出現
工廠方法優勢:
子類(lei)與子類(lei)是(shi)并(bing)列的,關(guan)系不精密,程序(xu)耦合度比較大
完全(quan)符(fu)合OCP原則,對代(dai)碼(ma)的修改關閉(bi),對代(dai)碼(ma)的擴展開放
創(chuang)建具體對象方(fang)法靈活,可以使用反射(she)或者第(di)三方(fang)IOC容(rong)器(qi)
工廠方法模式代碼片斷,主要從簡單工廠中修改過來的,下面是結果圖
1 統一(yi)操作行為,主要將統一(yi)接口抽象出來,讓具體子類(lei)去實(shi)現它(ta)
1 /// <summary> 2 /// 工廠方法的(de)規定操作(zuo)行為 3 /// </summary> 4 public interface ICreate 5 { 6 void Create(); 7 }
如(ru)果(guo)它的(de)(de)一部分(fen)功(gong)能對于(yu)子類是公用的(de)(de),相同的(de)(de),那我們需要將(jiang)ICreate設(she)計成(cheng)抽象類abstract class ,代碼可以是這樣
1 public abstract class CreateBase 2 { 3 /// <summary> 4 /// 每個子(zi)類都公用的屬(shu)性(xing)或者方法(fa) 5 /// </summary> 6 protected string CreateName 7 { 8 get 9 { 10 return "一個(ge)工廠方法模式"; 11 } 12 } 13 /// <summary> 14 /// 子類(lei)必須去實現的(de)抽象方法行為 15 /// </summary> 16 abstract void Create(); 17 }
而一個建立抽象行為的工(gong)(gong)(gong)廠(chang),它(ta)(ta)可以被其(qi)它(ta)(ta)具體行為工(gong)(gong)(gong)廠(chang)繼承,它(ta)(ta)提(ti)供一個方法,叫子(zi)(zi)類(lei)工(gong)(gong)(gong)廠(chang)去實現(xian)它(ta)(ta),并(bing)返回子(zi)(zi)類(lei)對象本(ben)身(shen)。同樣,根據業(ye)務需求,可以由抽象類(lei)實現(xian)
1 /// <summary> 2 /// 抽(chou)象工廠(chang)規定(ding)行為(wei) 3 /// </summary> 4 public interface CreateFactory 5 { 6 ICreate CreateObject(); 7 }
對于(yu)具體對象(xiang)而言,它(ta)們要做的就是去(qu)實現(xian)抽象(xiang)的行為,以下是一(yi)個(ge)人物(wu)類,它(ta)去(qu)實現(xian)Create方(fang)法。
1 /// <summary> 2 /// 具體對象(xiang)實(shi)現(xian) 3 /// </summary> 4 public class People : ICreate 5 { 6 7 #region ICreate 成員 8 9 public void Create() 10 { 11 Console.WriteLine("創建人類"); 12 } 13 14 #endregion 15 }
而對于具體工廠來說,主要作用是(shi)去(qu)創建(jian)一個具體對象的實例,代(dai)碼如下(xia):
1 /// <summary> 2 /// 具體(ti)工(gong)廠(chang)進(jin)行生(sheng)產(chan)對象 3 /// </summary> 4 public class PeopleFactory : CreateFactory 5 { 6 #region CreateFactory 成員 7 8 public ICreate CreateObject() 9 { 10 return new People(); 11 } 12 13 #endregion 14 }
以程序調用時,我們需要先去(qu)創建一個工(gong)廠(chang),然(ran)后再使用工(gong)廠(chang)中(zhong)的(de)方法,來(lai)完成我們的(de)操作
1 FactoryMethod.CreateFactory createFactory = new FactoryMethod.PeopleFactory(); 2 FactoryMethod.ICreate iCreate = createFactory.CreateObject(); 3 iCreate.Create();
而這時,我(wo)們看到,代(dai)碼有些不完美,那(nei)就是(shi)在(zai)創建具體工(gong)廠時還是(shi)出現了new,即還是(shi)存在(zai)著代(dai)碼間的(de)依賴,如何解除(chu)這樣(yang)依賴使(shi)代(dai)碼更加(jia)松耦合呢,這時,我(wo)們可以使(shi)用反射或者IOC
容器(qi)來解決這個問(wen)題:
1 string strfactoryName = ConfigurationManager.AppSettings["factoryName"]; 2 FactoryMethod.CreateFactory factory = (FactoryMethod.CreateFactory)Assembly.Load("FactoryMethod").CreateInstance("FactoryMethod." + strfactoryName); 3 FactoryMethod.ICreate create = factory.CreateObject(); 4 create.Create();
我們從代碼中可(ke)以看到(dao),具體工廠的創(chuang)建已(yi)經被(bei)約束到(dao)了配置文件(jian)中,這是我們可(ke)以接(jie)受的,呵呵。
事(shi)實(shi)上,微(wei)軟(ruan)自(zi)己(ji)在它(ta)的(de)組件(jian)中大大使用了工廠方法(fa)模(mo)式(shi),如(ru)MVC中的(de)Controller的(de)創(chuang)建方法(fa),也(ye)是這個(ge)道理。