跟着项目学设计模式(六):三层架构
前面用5個(gè)章節(jié)介紹了單例模式和工廠系列模式,這個(gè)過程中,如果算上網(wǎng)站開發(fā)人員的表示層,那么項(xiàng)目經(jīng)歷了二層到多層的演變:
數(shù)據(jù)訪問層+表示層 =》
數(shù)據(jù)訪問層+業(yè)務(wù)邏輯層+Client層+表示層
至此,這個(gè)系列中對創(chuàng)建型設(shè)計(jì)模式的介紹也到此為止了。后面的文章,我們會把關(guān)注點(diǎn)放到具體的代碼實(shí)現(xiàn)上,比如層與層之間如何調(diào)用,工廠模式與抽象工廠在代碼實(shí)現(xiàn)上的異同等等,這里面會涉及到很多結(jié)構(gòu)型設(shè)計(jì)模式相關(guān)的知識,由于代碼架構(gòu)變得愈加復(fù)雜,也只有請結(jié)構(gòu)型設(shè)計(jì)模式來救場。
那有人要問了,既然提升了系統(tǒng)復(fù)雜度,為什么要使用多層架構(gòu)?
什么是三層架構(gòu)?
為什么要用三層架構(gòu)?
為了達(dá)到“高內(nèi)聚,低耦合”的程序設(shè)計(jì)思想,引入了三層架構(gòu),在表現(xiàn)層和業(yè)務(wù)層分離開來,再加上數(shù)據(jù)訪問層,便形成了今天的三層架構(gòu)。
沒錯(cuò)上面又是百度百科的解釋,雖然這個(gè)答案簡練得連面試的要求都達(dá)不到,但無疑是百分百正確的答案,沒有摻雜任何個(gè)人理解的回答。初學(xué)者最不喜歡的就是這種答案,他們更喜歡的是富有個(gè)人強(qiáng)烈感情色彩的解釋,即使偏激。
來看摻雜了筆者個(gè)人理解,詳細(xì)到能應(yīng)付面試的解答:
要回答這個(gè)問題首先要知道什么是一層架構(gòu)和二層架構(gòu)
一層架構(gòu):只有一個(gè)表示層
二層架構(gòu):?第一層:表示層
? ? ? ? ? ? ? ? ? ?第二層:數(shù)據(jù)訪問層
沒錯(cuò),一層架構(gòu)就是只有一個(gè)表現(xiàn)層的架構(gòu)。您可能會有疑問:只有一個(gè)表示層,怎么可能?
這里以后OA系統(tǒng)的用戶模塊為例,給一個(gè)5-10人的小公司用,只需要一個(gè)管理員賬戶,用戶名密碼都是admin,所有人都用這一個(gè)賬號登錄,代碼里寫死就可以了,業(yè)務(wù)邏輯就是登陸的時(shí)候判斷? if(username=="admin"&&pwd=="admin")。
是的,你沒有任何理由來批判一層架構(gòu)的缺點(diǎn),因?yàn)榧軜?gòu)本身并沒有缺點(diǎn),只有適不適合。只是一個(gè)顯示"Hello World"的功能,是不需要分什么層的,當(dāng)然,如果非要有云"Hello World"這種需求,那就不好說了。
后來,使用OA的公司慢慢做大,成了幾百人的公司,OA系統(tǒng)需要增加考勤模塊作為主打功能,這意味著每個(gè)員工都需要一個(gè)用戶名來做考勤,而admin則負(fù)責(zé)管理用戶。我們需要在數(shù)據(jù)庫添加用戶表和門禁表。
管理員可以通過表單編輯用戶表中的性別、出生日期和照片,用戶只能編輯部分個(gè)人信息(照片和個(gè)性簽名)
管理員修改用戶信息
[Authorize("admin")] [HttpPost] public ActionResult?AdminEdit(User entity) {using(var context=new DBContext()){var user = context.Users.Where(d => d.id == entity.id).FirstOrDefault();user.sex=entity.sex;user.birth=entity.birth;user.photo=entity.photo;if(context.SaveChanges()>0){...}....} }用戶修改個(gè)人信息,我們把上面的代碼copy過來,略加修改就可以了。
[Authorize] [HttpPost] public ActionResult?UserEdit(User entity) {using(var context=new DBContext()){var user = context.Users.Where(d => d.id == entity.id).FirstOrDefault();user.photo=entity.photo;user.sign=entity.sign;if(context.SaveChanges()>0){...}....} }表示層中多個(gè)用戶表的編輯操作,造成了代碼的重復(fù),重復(fù)是遠(yuǎn)比壞味道還要嚴(yán)重的多的問題,我們修要提供一個(gè)通用的修改用戶信息的方法來優(yōu)化代碼:
private bool UpdateUser(User entity,params string[] columnNames) {...do Update... }[Authorize("admin")] [HttpPost] public ActionResult?AdminEdit(User entity) {//如果編輯成功if(UpdateUser(entity, "sex", "birth","photo")){...} }[Authorize] [HttpPost] public ActionResult?UserEdit(User entity) {//如果編輯成功if(UpdateUser(entity, "photo","sign")){...} }?一層架構(gòu)為解決數(shù)據(jù)庫操作造成的代碼重復(fù),不斷地提供的通用方法,他們分散在表示層中的各個(gè)角落,這便是數(shù)據(jù)訪問層的原型。
二層架構(gòu)將這些通用方法抽離成數(shù)據(jù)訪問層:
[Authorize("admin")] [HttpPost] public ActionResult?AdminEdit(User entity) {//如果編輯成功if(new UserDal().Update(entity, t => t.id == entity.id, "sex", "birth","photo")){...} }[Authorize] [HttpPost] public ActionResult?UserEdit(User entity) {//如果編輯成功if(new UserDal().Update(entity, t => t.id == entity.id, "photo","sign")){...} }所以,對于高質(zhì)量的代碼下的一層架構(gòu)來說,重構(gòu)成二層所帶來的改變僅僅是把對數(shù)據(jù)庫的通用方法拿出來,換個(gè)地方而已,并沒有其他任何復(fù)雜的改動。
{{
【能夠通過sonar代碼質(zhì)量檢查的一層架構(gòu)】 VS 【能夠通過sonar代碼質(zhì)量檢查的二層架構(gòu)】
優(yōu)點(diǎn):代碼好找(管理)了,以前是在本模塊里找,現(xiàn)在是在本模塊的某一層里面找,利于分工,使開發(fā)人員可以專注于某一層。
缺點(diǎn):維護(hù)起來變麻煩了,每次改動需要提交的文件變多了
具體要不要重構(gòu),看項(xiàng)目實(shí)際情況和個(gè)人喜好吧
----------------------------------------------------------------------------------------------------
【能夠通過sonar代碼質(zhì)量檢查的一層架構(gòu)】 VS 二層架構(gòu)
毫無疑問,二層架構(gòu)會被完爆!!!為什么?因?yàn)橹灰悄軌蛲ㄟ^sonar代碼質(zhì)量檢查的一層架構(gòu)重構(gòu)的二層架構(gòu),只是把代碼換了個(gè)位置,略加修改,肯定通過sonar代碼質(zhì)量檢查的。
所以【能夠通過sonar代碼質(zhì)量檢查的一層架構(gòu)】就約等于【能夠通過sonar代碼質(zhì)量檢查的二層架構(gòu)】
如果連一層架構(gòu)的代碼都組織不好,何談二層?
}}
?
-----------------------------------------------------------------------------------------------------------------------
如果后面項(xiàng)目需求變得更加復(fù)雜,業(yè)務(wù)規(guī)則、合法性校驗(yàn)等業(yè)務(wù)邏輯增多,高質(zhì)量代碼下的一層架構(gòu)肯定是提供了很多業(yè)務(wù)邏輯的通用方法,因此
高質(zhì)量代碼下的一層架構(gòu)可以隨意的重構(gòu)到二層和三層,物理文件的增加,代碼位置的變動,僅此而已。
所以呢,人們都說高手所見略同,模塊到了他們那群高手的手中,雖然在物理上并沒有分層,但是分層的思想已經(jīng)隨處可見了。獨(dú)孤求敗草木竹石皆可為劍,就是這個(gè)道理。
但是正如三國演義里,呂布說過:“我有赤兔馬方天戟,過河如履平地!”,這個(gè)時(shí)候陳宮說:“你有赤兔馬,你當(dāng)世無敵,但是將士們不行呀!”
你不能要求所有人都有那么高的水平,筆者去年參加的項(xiàng)目,也是多層架構(gòu),要求是代碼合格率達(dá)到60%就可以了,當(dāng)時(shí)寫代碼就跟應(yīng)付考試似的,實(shí)在是能力有限,但是進(jìn)度趕得緊。
要記住,是因?yàn)橥ㄓ梅椒ǖ某霈F(xiàn)才不得不在物理上分層,而不是分層之后,才去寫通用方法。如果一開始你分層的目的是妄圖通過分層達(dá)到變相的約束程序員去寫通用方法的做法,是很難實(shí)現(xiàn)的。
真正起到一些作用的是接口,是設(shè)計(jì)模式。我接口里聲明了這些方法,你就必須去實(shí)現(xiàn),而且要調(diào)用這些通用方法也只能通過接口,而設(shè)計(jì)模式來決定接口到底如何設(shè)計(jì),我單層架構(gòu)也可以用抽象工廠模式,你管我放哪兒干嘛?我就是把所有的接口和類全寫一個(gè)文件里它也是抽象工廠模式。
面試問題:
什么是三層架構(gòu):
從三層架構(gòu)的視角來看一層和二層:
一層架構(gòu):包含復(fù)雜數(shù)據(jù)庫操作和業(yè)務(wù)邏輯的表示層
二層架構(gòu):?第一層:包含復(fù)雜業(yè)務(wù)邏輯的表示層
? ? ? ? ? ? ? ? ? ?第二層:數(shù)據(jù)訪問層
為了達(dá)到“高內(nèi)聚,低耦合”的程序設(shè)計(jì)思想,引入了三層架構(gòu),將表現(xiàn)層和業(yè)務(wù)層分離開來,把業(yè)務(wù)規(guī)則、數(shù)據(jù)訪問、合法性校驗(yàn)等通用方法都放到了中間層進(jìn)行處理,再加上數(shù)據(jù)訪問層,便形成了三層架構(gòu)。
?
三層架構(gòu)的優(yōu)缺點(diǎn):
【能夠通過sonar代碼質(zhì)量檢查的一(二)層架構(gòu)】 VS 【能夠通過sonar代碼質(zhì)量檢查的三層架構(gòu)】
【能夠通過sonar代碼質(zhì)量檢查的二層架構(gòu)】?約等于【能夠通過sonar代碼質(zhì)量檢查的三層架構(gòu)】只是通用方法位置不同。
優(yōu)點(diǎn):代碼好找(管理)了,以前是在本模塊里找,現(xiàn)在是在本模塊下的某一層里面找,利于分工,使開發(fā)人員專注于某一層。
缺點(diǎn):維護(hù)起來變麻煩了,每次改動需要提交的文件變多了
?
【能夠通過sonar代碼質(zhì)量檢查的一(二)層架構(gòu)】 VS 【三層架構(gòu)】
沒有可比性,架構(gòu)本身并不能解決代碼質(zhì)量的問題。
真正起到一些作用的是接口,是設(shè)計(jì)模式。設(shè)計(jì)模式通過接口約束必須實(shí)現(xiàn)哪些方法,層與層之間只能調(diào)用通過接口中聲明的方法。這在某種程度上是一種限制,但并不影響我在具體的實(shí)現(xiàn)該方法的代碼里,究竟干了什么。
?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的跟着项目学设计模式(六):三层架构的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 搭配emuc-b202 can卡通讯时,
- 下一篇: .Net Web微信H5鱼虾蟹网站开发搭