分层架构
.NET簡(jiǎn)談分層架構(gòu)思想(徹底分離每個(gè)層)
提到分層,我就想起一句圖靈獎(jiǎng)獲得者說(shuō)過(guò)的話:計(jì)算機(jī)科學(xué)領(lǐng)域任何問(wèn)題,都可以間接的通過(guò)添加一個(gè)中間層來(lái)解決;當(dāng)初看到這句話的時(shí)候還不能深刻的體會(huì)到這句話的真正靈魂是什么。之所以要寫(xiě)這篇文章作為技術(shù)愛(ài)好者之一更愿意與大家分享技術(shù)給我們帶來(lái)的快樂(lè),本人將從另一個(gè)角度來(lái)解析.NET分層架構(gòu)的真正奧秘。分層,一些技術(shù)功底比較薄弱的程序員聽(tīng)到分層就會(huì)聯(lián)想到三層架構(gòu)(BLL,DAL之類(lèi)的),其實(shí)不是,分層是一個(gè)很大的技術(shù)框架思想,三層架構(gòu)只不過(guò)是對(duì)普通的信息系統(tǒng)來(lái)說(shuō),將信息的流轉(zhuǎn)通過(guò)三層來(lái)分解,在開(kāi)發(fā)系統(tǒng)時(shí)一般總會(huì)在解決方案中新建一個(gè)Model層、一個(gè)BLL層、然后DAL層;其實(shí)如果是這樣建項(xiàng)目的話跟一個(gè)解決方案中放上一個(gè)程序一樣的只不過(guò)可以用文件夾分開(kāi)建立文件是一回事;技術(shù)水品的不同對(duì)三層的理解各不相同,有時(shí)會(huì)加上一個(gè)接口層讓每層依賴(lài)接口來(lái)實(shí)現(xiàn),像上面的BLL、DAL之類(lèi)的架構(gòu),只是人為的分解感覺(jué)解決方案看上去很清晰一幕了然,對(duì)框架來(lái)說(shuō)沒(méi)有什么分離作用,還是高耦合低類(lèi)聚;
在分層架構(gòu)中,是從總體上對(duì)系統(tǒng)進(jìn)行一個(gè)分層,里面涉及縱橫向的概念,一個(gè)大的系統(tǒng)從業(yè)務(wù)邏輯來(lái)講可以不是單單的對(duì)信息的處理,也可能涉及到對(duì)一些其他的邏輯處理,這里就不能單單的把邏輯抽象到三層中,三層是橫向分層中的一個(gè)層,如果對(duì)分層的焦距拉遠(yuǎn)點(diǎn)看是看不到三層的,如果把焦距拉近點(diǎn)看也許目標(biāo)不會(huì)鎖定在信息流的處理子層中,說(shuō)起來(lái)比較抽象來(lái)個(gè)圖吧;
上圖中將一個(gè)大的系統(tǒng)分解為三個(gè)業(yè)務(wù)邏輯塊其實(shí)也就是我所說(shuō)的三個(gè)大的層面,我們將焦距拉近看業(yè)務(wù)邏輯1中的子層;
邏輯1這個(gè)大層被分解為兩個(gè)子層BLL、和DAL,也就是我們常用的業(yè)務(wù)邏輯層和數(shù)據(jù)訪問(wèn)層;業(yè)務(wù)邏輯1層中主要是用來(lái)對(duì)數(shù)據(jù)庫(kù)的增、刪、改、查操作,將其抽象成BLL和DAL也是我們所熟悉的三層;在另外兩個(gè)業(yè)務(wù)邏輯層中一樣可以將其分解層多道子層;將子層分開(kāi)后就要涉及到具體實(shí)現(xiàn)的問(wèn)題了,就拿C#面向?qū)ο笳Z(yǔ)言來(lái)將,架構(gòu)跟思想都是一些方法論的東西,具體實(shí)現(xiàn)是少不了的;層是分好了是否在開(kāi)發(fā)過(guò)程中真真做到層層隔離,不互相依賴(lài),所以是用接口層分割開(kāi)來(lái),將具體的實(shí)現(xiàn)層脫離開(kāi)來(lái),我們將BLL層改為BLL接口層BLLI,將DAL層改為DAL接口層DALI,這樣讓BLL、DAL去實(shí)現(xiàn)BLLI和DALI接口,完全分離開(kāi)發(fā),這也是面向?qū)ο笏岢拿嫦蚪涌诰幊潭皇敲嫦驅(qū)崿F(xiàn)編程;
以后BLL層出現(xiàn)問(wèn)題可以完全替換掉換另一個(gè)BLL層,DAL層同樣也一樣;但是這是思想性的東西落實(shí)到代碼還沒(méi)那么簡(jiǎn)單:
如:BLLI B=new BLL();//在通常情況下是這樣去用接口的,但是似乎沒(méi)有理論說(shuō)的那么干凈的分離,我們?cè)谕ㄟ^(guò)添加一個(gè)工廠來(lái)實(shí)現(xiàn)分離;
這樣在使用時(shí):BLLI B=new BLLI工廠(BLLI接口類(lèi)型);在調(diào)用工廠的時(shí)候?qū)⒔涌诘念?lèi)型做為參數(shù)傳進(jìn)去,在工廠中在通過(guò)接口類(lèi)型去查找具體的實(shí)現(xiàn)對(duì)象;如:
??????? public static T GetInterfaceRealization<T>(Type interfacetype)
??????? {
??????????? Assembly ass = Assembly.LoadFrom("程序集的名稱(chēng)");
??????????? Type[] asstype = ass.GetTypes();
??????????? if (asstype.Length <= 0)
??????????????? throw new Exception("接口管理器的異常:該程序集沒(méi)有任何實(shí)現(xiàn)類(lèi)");
??????????? for (int i = 0; i < asstype.Length; i++)
??????????? {
??????????????? //獲取該實(shí)現(xiàn)類(lèi)的整個(gè)繼承鏈中是否有傳入的接口類(lèi)型;
??????????????? Type oddinterfacetype = asstype[i].GetInterface(interfacetype.Name);
??????????????? if (oddinterfacetype != null)
??????????????? {
??????????????????? T t = (T)System.Activator.CreateInstance(asstype[i]);
??????????????????? return t;//返回動(dòng)態(tài)實(shí)例化的接口實(shí)現(xiàn)類(lèi);
??????????????? }
??????????? }
??????????? throw new Exception("接口管理器的異常:沒(méi)有該接口的實(shí)現(xiàn)類(lèi),必須先實(shí)現(xiàn)接口類(lèi)才能查找");
??????? }
?因?yàn)橥粋€(gè)解決方案中的不同項(xiàng)目彼此直接引用時(shí),有利于項(xiàng)目的開(kāi)發(fā)調(diào)試,但是我們的BLL和調(diào)用方是完全沒(méi)有任何依賴(lài)的在程序調(diào)用時(shí)候沒(méi)有任何類(lèi)型的調(diào)用所以在解決方案生成的時(shí)候不會(huì)將我們引用的項(xiàng)目程序集拷貝到執(zhí)行目錄中,如果想省略手工操作可以在執(zhí)行查找的時(shí)候先調(diào)用一下實(shí)現(xiàn)層的對(duì)象,這樣當(dāng)編譯生成的時(shí)候代碼檢查到你有調(diào)用會(huì)將你調(diào)用的項(xiàng)目程序集拷貝到執(zhí)行目錄中,在通過(guò)接口工廠動(dòng)態(tài)查找時(shí)不會(huì)失敗;
這樣就徹底的實(shí)現(xiàn)層層分離的規(guī)則
轉(zhuǎn)載于:https://www.cnblogs.com/s1297-lgy/p/6639314.html
總結(jié)
- 上一篇: 20道你必须要背会的微服务面试题,面试一
- 下一篇: 《武义九州》隐私政策