一、上篇回顧
上篇我們主要講述了抽象工廠模式和工廠模式。并且分析了該模式的應(yīng)用場(chǎng)景和一些優(yōu)缺點(diǎn),并且給出了一些實(shí)現(xiàn)的思路和方案,我們現(xiàn)在來(lái)回顧一下:
抽象工廠模式:一個(gè)工廠負(fù)責(zé)所有類(lèi)型對(duì)象的創(chuàng)建,支持無(wú)縫的新增新的類(lèi)型對(duì)象的創(chuàng)建。這種情況是通過(guò)配置文件來(lái)實(shí)現(xiàn)的,通過(guò)字典映射的方式來(lái)實(shí)現(xiàn),不過(guò)可能效率上有點(diǎn)低下,可以通過(guò)優(yōu)化的方式
來(lái)做,上篇中我們也給出了委托的工廠實(shí)現(xiàn)形式,相比之前的簡(jiǎn)單工廠模式和工廠模式有了更好的靈活性,并且對(duì)具有依賴關(guān)系或者組合關(guān)系的對(duì)象的創(chuàng)建尤為適合。
上篇中,有不少的朋友提出了一些意見(jiàn)和建議,首先很感謝大伙的支持和鼓勵(lì),有朋友提出來(lái),我畫(huà)的圖不夠?qū)I(yè),專(zhuān)業(yè)人士應(yīng)該用UML建模圖來(lái)搞,我怎么說(shuō)呢?我也同意這樣的說(shuō)法,但是我發(fā)現(xiàn)我通過(guò)
另外的直觀的圖形,大家一看就能更明白,結(jié)合代碼,當(dāng)然好的UML圖,已經(jīng)能表述清楚設(shè)計(jì)的思路和大體實(shí)現(xiàn)了,不過(guò)說(shuō)實(shí)話,我看著就有點(diǎn)類(lèi),特別是UML圖復(fù)雜的時(shí)候。所以我還是暫時(shí)先用這種一般的圖
形來(lái)表述我理解的設(shè)計(jì)模式的思想,看看大伙是什么看法和意見(jiàn),如果說(shuō)都說(shuō)說(shuō)UML圖的話,那么后面的相關(guān)模式,我會(huì)主要以UML專(zhuān)業(yè)圖來(lái)繪制。
我這里總結(jié)下我們以后項(xiàng)目中的可能會(huì)用到設(shè)計(jì)模式 之處或者系統(tǒng)架構(gòu)的時(shí)候,一般情況下有這樣的幾類(lèi)方案,我們可以在考慮系統(tǒng)的低耦合性的時(shí)候的設(shè)計(jì):
基本上來(lái)說(shuō)能掌握上面的幾類(lèi)情況,基本上設(shè)計(jì)出來(lái)的系統(tǒng)至少是可用的,不知道大家有沒(méi)有更多意見(jiàn)和建議。有的請(qǐng)?zhí)岢鰜?lái),我會(huì)備
注在文章中。
二、摘要
本文主要是針對(duì)創(chuàng)建型模式中的創(chuàng)建者模式進(jìn)行講述,創(chuàng)建者模式是創(chuàng)建型模式中最負(fù)責(zé)的一個(gè)設(shè)計(jì)模式了,創(chuàng)建者負(fù)責(zé)構(gòu)建一個(gè)對(duì)象的各個(gè)部分,并且完成組裝的過(guò)程,我們可以這么理解創(chuàng)建
者模式,創(chuàng)建者模式類(lèi)似與一個(gè)步驟基本固定,但是每個(gè)步驟中的具體形式卻又可以變化的這類(lèi)對(duì)象的創(chuàng)建。也許這樣說(shuō)還是太抽象了,我們這么來(lái)理解吧,我感覺(jué)讓人最容易理解的形式還是圖形化
的形式,不但接受起來(lái)容易,并且讓人映象深刻,不知道大家是不是和我有同感呢?下面我們給出一個(gè)簡(jiǎn)單的例子,通過(guò)圖形化的流程來(lái)說(shuō)明吧:我們這里以我們大伙平時(shí)最常見(jiàn)的做飯為例吧:
可能我這里給出的流程只是我個(gè)人理解的或者看到的過(guò)程,不代表全部,呵呵,這里只是事例性的說(shuō)明。
三、本文大綱
a、上篇回顧。
b、摘要。
c、本文大綱。
d、創(chuàng)建者模式的特點(diǎn)及使用場(chǎng)景。
e、創(chuàng)建者模式的實(shí)現(xiàn)方案。
f、創(chuàng)建者模式使用總結(jié)。
g、系列進(jìn)度。
h、下篇預(yù)告。
四、創(chuàng)建者模式的特點(diǎn)及使用場(chǎng)景
創(chuàng)建者模式主要是用于創(chuàng)建復(fù)雜的一些對(duì)象,這些對(duì)象的創(chuàng)建步驟基本固定,但是可能具體的對(duì)象的組成部分卻又可以自由的變化,現(xiàn)實(shí)中的例子很多,但是可能大伙都比較容易理解的就是,我
們的自己花錢(qián)配置的臺(tái)式機(jī)或者筆記本,可以 這樣理解,這些硬件設(shè)備的各個(gè)零件,不管是CPU是Intel的還是AMD的,顯卡是華碩的還是小影霸的,不管硬盤(pán)是西部數(shù)據(jù)的還是希捷的,其實(shí)想表述
的意思就是對(duì)象的具體的組成部分可以是變化的,但是可能我們發(fā)現(xiàn)對(duì)象的這些組成部分的組織起來(lái)的過(guò)程是相對(duì)固定的,那么我們就可以用創(chuàng)建者模式來(lái)做,并且我們引入一個(gè)引導(dǎo)者(Director)來(lái)
引導(dǎo)這個(gè)對(duì)象的組裝過(guò)程??梢院?jiǎn)單用圖形化的過(guò)程來(lái)描述如下:
我們上面說(shuō)明了一個(gè)服裝的大概生產(chǎn)過(guò)程,這里生產(chǎn)的順序可能會(huì)發(fā)生變化,或者
生產(chǎn)的帽子,上衣等都會(huì)發(fā)生變化,但是服裝的組裝過(guò)程基本上變化不大,都是需要帽子,上衣,褲子的,這時(shí)候我們可以通過(guò)引導(dǎo)著負(fù)責(zé)組裝這樣的過(guò)程,然后我們?cè)诰唧w的每個(gè)部分可以是抽象接
口,根據(jù)不同的實(shí)現(xiàn)創(chuàng)建不同的帽子來(lái)完成變化。
五、創(chuàng)建者模式的實(shí)現(xiàn)方案
5.1、經(jīng)典的創(chuàng)建者模式實(shí)現(xiàn)
-
* 我們先給出經(jīng)典創(chuàng)建者模式的一個(gè)實(shí)現(xiàn)形式,然后針對(duì)這個(gè)經(jīng)典模式后面提出幾個(gè)改進(jìn)方案,我們這里以上面講述的服裝的過(guò)程作為例子來(lái)說(shuō)明下創(chuàng)建者模式的原理和思想,希望大家也能靈活的運(yùn)用到實(shí)際的項(xiàng)目中去。達(dá)到學(xué)以致用的目的。
我們來(lái)看看具體的代碼實(shí)現(xiàn):
/// <summary> /// 創(chuàng)建對(duì)象組織的所有構(gòu)造步驟接口 /// </summary> public interface IBuider { void BuilderPart1(); void BuilderPart2(); void BuilderPart3(); }
定義一個(gè)服裝對(duì)象:
/// <summary> /// 服裝對(duì)象 /// </summary> public class Dress { /// <summary> /// 構(gòu)建帽子 /// </summary> public void BuildHat() { throw new NotImplementedException(); } /// <summary> /// 構(gòu)建上衣 /// </summary> public void BuilderWaist() { throw new NotImplementedException(); } /// <summary> /// 構(gòu)建褲子 /// </summary> public void BuilderTrousers() { throw new NotImplementedException(); } }
實(shí)現(xiàn)創(chuàng)建對(duì)象的具體步驟:
public class Builder : IBuider { private Dress _dress; public Builder(Dress dress) { this._dress = dress; } public void BuilderPart1() { this._dress.BuildHat(); } public void BuilderPart2() { this._dress.BuilderWaist(); } public void BuilderPart3() { this._dress.BuilderTrousers(); } public Dress Build() { return this._dress; } }
通過(guò)指導(dǎo)者指導(dǎo)對(duì)象的創(chuàng)建,而具體的對(duì)象的創(chuàng)建還是靠對(duì)象本身提供的相應(yīng)方法,Builder只是調(diào)用對(duì)象的方法完成組裝步驟。Builder內(nèi)部提供一個(gè)返回構(gòu)造后完整對(duì)象的方法,上面給出的方法是
Build()方法。
/// <summary> /// 指導(dǎo)者 /// </summary> public class Director { public void Build(IBuider builder) { builder.BuilderPart1(); builder.BuilderPart2(); builder.BuilderPart3(); } }
通過(guò)上面的代碼,我們給出了經(jīng)典創(chuàng)建者模式的核心代碼形式,那么針對(duì)上面無(wú)疑有以下的幾個(gè)缺點(diǎn):
1、Ibuilder接口必須定義完整的組裝流程,一旦定義就不能隨意的動(dòng)態(tài)修改。
2、Builder與具體的對(duì)象之間有一定的依賴關(guān)系,當(dāng)然這里可以通過(guò)接口來(lái)解耦來(lái)實(shí)現(xiàn)靈活性。
3、Builder必須知道具體的流程。
那么針對(duì)上面的幾個(gè)問(wèn)題,我們?nèi)绾蝸?lái)解決呢?我想前面的創(chuàng)建型模式已經(jīng)給我了足夠的經(jīng)驗(yàn),還是通過(guò)配置文件或者其他的形式來(lái)提供靈活性。
-
5.2、創(chuàng)建者模式特性+委托實(shí)現(xiàn)
針對(duì)上面講述的例子我們可以考慮如下的方式進(jìn)行改進(jìn):
我們先定義一個(gè)構(gòu)造每個(gè)對(duì)象部分的委托,并且這個(gè)方法的參數(shù)是動(dòng)態(tài)變化的:
/// <summary> /// 定義通用的構(gòu)造部分的委托 /// </summary> public delegate void BuildHandler(params object[] items);
我們通過(guò)定義標(biāo)記來(lái)標(biāo)識(shí)對(duì)象中的每個(gè)部分的構(gòu)造步驟
/// <summary> /// 為對(duì)象中的每個(gè)步驟打上標(biāo)記 /// </summary> [AttributeUsage(AttributeTargets.Method,AllowMultiple=false)] public class BuildAttribute : Attribute { private MethodInfo hander; private int stepSort; public MethodInfo BuildHandler { get { return this.hander; } set { this.hander = value; } } public int StepSort { get { return this.stepSort; } set { this.stepSort = value; } } }
構(gòu)造對(duì)象的統(tǒng)一接口
/// <summary> /// 創(chuàng)建對(duì)象組織的所有構(gòu)造步驟接口 /// </summary> public interface IBuider { void Build<T>() where T : class,new(); }
下面給出具體的Builder的緩存實(shí)現(xiàn)方案代碼
public class CommonBuilder : IBuider { /// <summary> /// 緩存每個(gè)對(duì)象的具體的構(gòu)造步驟 /// </summary> private Dictionary<Type, List<BuildHandler>> steps = null; public void Build<T>(T ob) where T : class, new() { //從緩存中讀取指定類(lèi)型的項(xiàng) List<BuildHandler> handlers = steps[typeof(T)]; foreach (BuildHandler handler in handlers) { handler(); } } }
給出一些獲取某個(gè)類(lèi)型內(nèi)部的所有具有我們的自定義特性標(biāo)記的MethodInfo列表
public List<MethodInfo> GetMethodInfoList<T>() where T : class, new() { //從緩存中讀取指定類(lèi)型的項(xiàng) List<MethodInfo> methods = new List<MethodInfo>(); T target = new T(); MethodInfo[] methodList= typeof(T).GetType().GetMethods(); BuildAttribute[] attributes = null; foreach (MethodInfo info in methodList) { attributes= (BuildAttribute[])info.GetCustomAttributes(typeof(BuildAttribute), true); if (attributes.Length > 0) methods.Add(info); } return methods; }
獲取所有的特性,一般使用這個(gè)方法即可獲取所有的具有標(biāo)記該特性的方法列表和相應(yīng)的步驟:
public List<BuildAttribute> GetBuildAttributeList<T>() where T : class, new() { List<BuildAttribute> attributes = new List<BuildAttribute>(); BuildAttribute[] attributeList = null; BuildAttribute attribute = null; foreach (MethodInfo info in this.methods) { //設(shè)置特性中要執(zhí)行的方法 attributeList = (BuildAttribute[])info.GetCustomAttributes(typeof(BuildAttribute), true); if (attributeList.Length > 0) { attribute = attributeList[0]; attribute.BuildHandler = info; attributes.Add(attribute); } } //緩存步驟 steps.Add(typeof(T), attributes); return attributes; }
具體的Build中的調(diào)用代碼實(shí)現(xiàn):
public T Build<T>(T ob) where T : class, new() { List<BuildAttribute> attributeList = GetBuildAttributeList<T>(); T target=new T(); //構(gòu)造對(duì)象的過(guò)程 foreach (BuildAttribute item in attributeList) { item.BuildHandler.Invoke(target,null); } return target; }
這樣我們就完成了一個(gè)通用的基于標(biāo)記的自動(dòng)發(fā)現(xiàn)某個(gè)類(lèi)型的標(biāo)記方法步驟的通用代碼實(shí)現(xiàn),可能大家感覺(jué)這樣的方式還是挺麻煩的,那么我們還有沒(méi)有更好的改進(jìn)方案呢?因?yàn)槊看未驑?biāo)記我還是感
覺(jué)挺麻煩的,而且代碼量分布的也比較廣泛,我想通過(guò)統(tǒng)一配置管理的方式,當(dāng)然也是可以的,那么我們可以通過(guò)下面的方式來(lái)進(jìn)行擴(kuò)展。
-
5.3、創(chuàng)建者模式配置文件方式實(shí)現(xiàn)
配置文件的方式實(shí)現(xiàn)創(chuàng)建者,這個(gè)怎么說(shuō)呢,上面的抽象工廠的模式中,我們主要采用了這樣的方式來(lái)實(shí)現(xiàn)配置的靈活性和擴(kuò)展性,其實(shí)創(chuàng)建者也是一樣的,我們來(lái)看看配置文件吧,我想
就看配置文件就大概知道了,具體的應(yīng)用代碼了,請(qǐng)看下圖,粗略描述了實(shí)現(xiàn)的思路:
我這里給出配置文件的父子級(jí)節(jié)點(diǎn)示例:
<?xml version="1.0" encoding="utf-8" ?> <Build> <BuildClass name="ClassName" type="ClassType"> <BuildStep StepOrder="1" MethodName="MethodName1"/> <BuildStep StepOrder="2" MethodName="MethodName2" /> </BuildClass> <BuildClass name="ClassName1" type="ClassType1"> <BuildStep StepOrder="1" MethodName="MethodName1"/> <BuildStep StepOrder="2" MethodName="MethodName2" /> </BuildClass> </Build>
我們這里通過(guò)在Build實(shí)現(xiàn)中讀取配置文件中的所有的步驟,放在字典中。給出示例代碼
/// <summary> /// 創(chuàng)建對(duì)象組織的所有構(gòu)造步驟接口 /// </summary> public class Buider : IBuider { private Dictionary<Type, List<MethodInfo>> steps = null; public Buider() { steps = new Dictionary<Type, List<MethodInfo>>(); //讀取配置文件! //將配置文件中的類(lèi)名和方法名取出,然后通過(guò)反射取到這個(gè)類(lèi)型下的所有方法,根據(jù)配置中的步驟和方法名添加到 //步驟列表中,然后緩存到字典中 steps.Add(Type.GetType(""), new List<MethodInfo>()); } public T Build<T>() where T: class,new() { T target = new T(); //從字典中找到對(duì)應(yīng)的緩存列表,執(zhí)行構(gòu)造過(guò)程 List<MethodInfo> list = steps[typeof(T)]; //執(zhí)行構(gòu)造 foreach (MethodInfo info in list) { info.Invoke(target, null); } return target; } }
通過(guò)上面的幾步配置就可以完成相應(yīng)的構(gòu)建過(guò)程,這時(shí)候我們的指導(dǎo)者的工作就簡(jiǎn)單了,就是只是簡(jiǎn)單的通過(guò)使用Build中的通用方法
public class Director { public void Build<T>(IBuider builder) where T:class,new() { builder.Build<T>(); } }
只要通過(guò)上面的步驟就完成了創(chuàng)建者模式的通用實(shí)現(xiàn)方案。
六、創(chuàng)建者模式使用總結(jié)
通過(guò)上面的給出的幾類(lèi)不同的實(shí)現(xiàn)方案我們知道,創(chuàng)建者模式是一個(gè)對(duì)對(duì)象的構(gòu)建過(guò)程“精細(xì)化”的構(gòu)建過(guò)程,每個(gè)部分的構(gòu)建可能是變化的,但是對(duì)象的組織過(guò)程是固定的,通過(guò)這種統(tǒng)一的創(chuàng)建方
式,無(wú)疑增加了我們?cè)O(shè)計(jì)上的靈活性,當(dāng)我們?cè)跇?gòu)建復(fù)雜對(duì)象的時(shí)候,我們?nèi)绻l(fā)現(xiàn)每個(gè)部分可能都是變化的,并且是多個(gè)不同的構(gòu)建步驟的時(shí)候,我們可以考慮使用創(chuàng)建者模式。相比我們之前講述
的工廠和抽象工廠模式區(qū)別還是很大的,我們發(fā)現(xiàn)創(chuàng)建者適合這類(lèi)復(fù)雜對(duì)象的創(chuàng)建,對(duì)于抽象工廠可能就無(wú)法完成這樣的組裝工作,而且創(chuàng)建者模式是把復(fù)雜對(duì)象的內(nèi)部創(chuàng)建方法進(jìn)行調(diào)用,組織協(xié)調(diào)
了對(duì)象的各個(gè)部分前后順序的控制。簡(jiǎn)單的描述創(chuàng)建者就是這樣的情況:
由于本人水平有限,或者講述能力有限,表達(dá)思路錯(cuò)誤或者想法錯(cuò)誤,請(qǐng)大家批評(píng)指出,如果您有更好的意見(jiàn)或者想法,請(qǐng)?zhí)岢鲇懻?,歡迎大家提出寶貴意見(jiàn)和建議。
七、系列進(jìn)度。
創(chuàng)建型
1、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-單件模式
2、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-工廠模式
3、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-抽象工廠模式
4、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-創(chuàng)建者模式
5、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-原型模式
結(jié)構(gòu)型
1、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-組合模式
2、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-外觀模式
3、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-適配器模式
4、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-橋模式
5、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-裝飾模式
6、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-享元模式
7、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-代理模式
行為型
1、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-命令模式
2、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-觀察者模式
3、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-策略模式
4、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-職責(zé)模式
5、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-模板模式
6、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-中介者模式
7、系統(tǒng)架構(gòu)技能之設(shè)計(jì)模式-解釋器模式
八、下篇預(yù)告。
下篇將會(huì)針對(duì)原型模式進(jìn)行講述,該模式也是創(chuàng)建型模式中很有特點(diǎn)設(shè)計(jì)模式之一,該 模式是利用現(xiàn)有的一個(gè)對(duì)象進(jìn)行克隆的過(guò)程產(chǎn)生一個(gè)新的對(duì)象,當(dāng)然這里的復(fù)制對(duì)象可以是2種,深復(fù)制和淺復(fù)
制,在這個(gè)系列的總結(jié)中如果您有好的想法或者創(chuàng)意,請(qǐng)?zhí)岢鰜?lái),希望大家多提寶貴意見(jiàn),錯(cuò)誤之處還請(qǐng)指出,請(qǐng)大家繼續(xù)支持。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-694287.html
轉(zhuǎn)自:https://www.cnblogs.com/hegezhou_hot/archive/2010/12/02/1894771.html文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-694287.html
到了這里,關(guān)于設(shè)計(jì)模式系列-創(chuàng)建者模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!