天天看點

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

 本章内容主要包括兩個方面,一、是架構分層(控制器、業務對象、實體、Dao)的詳細說明,二、是對比常用三層結構的差別和優勢;

本文要點:

1.架構中的各個分層詳細說明

2.對比常用三層結構的差別和優勢

3.分享兩個項目中的小經驗

4.網絡資料

我們先看一下前面執行個體中的解決方案目錄:

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

我們再看各層之間的調用關系:

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

上圖描叙的控制器有四種方式來操作資料庫,

1)控制器調用實體,通過架構中的ORM來實作單表的操作

2)控制器直接操作資料庫對象(oleDB),通過編寫SQL語句通路資料庫

3)控制器通過調用Dao操作資料庫

4)控制器調用業務對象,業務對象再調用Dao操作資料庫

還有就是每一層在程式結構中承擔的角色;

一、Dao

       資料通路對象,建立一個Dao必須繼承繼承架構中的AbstractDao對象,AbstractDao對象中封裝了資料庫操作對象oleDb,是以Dao中的方法都是直接編寫SQL語句操作資料庫;

public class BookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao
    {
        public DataTable GetBooks(string searchChar, int flag)
        {
            string strsql = @"SELECT * FROM dbo.Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
            strsql = string.Format(strsql, searchChar, flag);
            return oleDb.GetDataTable(strsql);
        }
      }      

上面代碼是實作對Sqlserver資料庫的操作,如果要實作不同資料庫的操作,如:Oracle、DB2等,要如何實作?很簡單,先建立IBookDao接口,再分别實作SqlBookDao和OracleBookDao,控制器通路Dao隻需調用IBookDao接口就行了,而最後操作哪個資料庫的Dao在EFWUnity.config配置檔案中配置好。

IBookDao接口

  public interface IBookDao
        {
        System.Data.DataTable GetBooks(string searchChar, int flag);
      }      

SqlBookDao對象

public class SqlBookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao, Books.Dao.IBookDao
    {
        public DataTable GetBooks(string searchChar, int flag)
        {
            string strsql = @"SELECT * FROM dbo.Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
            strsql = string.Format(strsql, searchChar, flag);
            return oleDb.GetDataTable(strsql);
        }
      }      

OracleBookDao對象

public class OracleBookDao : EFWCoreLib.CoreFrame.BusinessArchitecture.AbstractDao, Books.Dao.IBookDao
    {
        public DataTable GetBooks(string searchChar, int flag)
        {
            string strsql = @"SELECT * FROM Books WHERE BookName LIKE '%{0}%' AND Flag={1}";
            strsql = string.Format(strsql, searchChar, flag);
            return oleDb.GetDataTable(strsql);
        }
      }      

EFWUnity.config配置檔案

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

控制器中通過NewDao<>操作方法,建立配置的SqlBookDao對象

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

綜合上述,不同資料庫Dao結構設計如下:

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

二、Entity實體

        實體代碼都是用工具,根據資料庫表結構資訊生成的;所有實體都必須繼承架構中的AbstractEntity對象,而實體與資料庫表之間的映射不需要另外xml配置檔案,而是利用自定義标簽實作ORM映射;TableAttribute标簽映射實體類名與資料庫表,ColumnAttribute标簽映射實體屬性與資料庫表字段。一個實體映射到多個表也可以,直接類名上配置多個TableAttribute标簽和屬性上配置多個ColumnAttribute标簽,不過要用标簽的Alias參數區分。

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

三、ObjectModel業務對象

        業務對象在書籍管理執行個體并沒有建此對象,因為業務太簡單了,隻有當業務流程很複雜或範圍涉及廣的情況,就可以考慮建一些業務對象來解決這些問題;所有業務對象必須繼承架構中的AbstractBusines對象,業務對象中不能直接操作資料庫,必須通過Dao來通路。另外就是如果多個業務對象是用來解決同一個問題,一般我們使用工廠模式來設計,在架構中可以使用EFWUnity.config配置檔案進行業務對象映射;

十、EnterpriseFrameWork架構的分層架構及意義(控制器、業務對象、實體、Dao之間關系)

四、Controller控制器,包括WebController、WinController、WcfController、WcfClientController

        控制器分為3種模式,不同模式分别建控制器。控制器在程式結構中的作用就是承上啟下,比如WebController控制器,就是把調用邏輯層傳回的資料結構轉換為統一Json字元串傳遞給界面JqueryEasyUI。而不同的界面架構則需要對架構中的Webcontroller進行擴充,以後我們會詳細講解各種控制器的實作;

還有就是Controller中提供了資料庫的操作對象OleDB,允許控制器直接編寫SQL語句操作資料庫,為什麼要放開此功能,這也是在項目中遇到的實際情況而不得不妥協的一種設計;

同樣所有控制器也都必須架構中的基類控制器,基于JqueryEasyUI的Webcontroller繼承AbstractJqueryController對象,WinController繼承BaseController對象,wcfController繼承JsonWCFController對象;wcfClientController繼承BaseWCFClientController對象;

再就是控制器暴露給界面UI,還必須加上控制器的自定義标簽,WebController的WebController和WebMethod,WinController的Menu,wcfClientController的WCFController和WCFMethod;

        通過上面的介紹,應該對EnterpriseFrameWork架構的分層結構有一定得了解,下面我們讨論一下,與常用三層結構的差別與優勢?

        軟體分層意義主要就包括解耦和複用,也許還能讓代碼維護與擴充更友善;三層結構分别包括界面層、邏輯層和資料層。EnterpriseFrameWork架構中的分層也可以說是三層,隻是叫法與承擔的職責不一樣,并且EnterpriseFrameWork架構中的分層可以随時變化的,不同情況有4種方式對分層進行調整,是以EnterpriseFrameWork架構分層的相容性強。有哪些不同情況,可以總結為兩種,一是根據具體功能的難易程度,二是根據開發人員的代碼水準;

我們對比一下PetShop項目的程式結構:

PetShop項目名稱及描述:(實作步驟為:4-3-6-5-2-1) 

1、WEB=表示層 

2、BLL=業務邏輯層

3、IDAL=資料通路層接口定義 

4、Model=業務實體 

5、DALFactory=資料層的抽象工廠(建立反射) 

6、SQLServerDAL=SQLServer資料通路層 / OracleDAL=Oracle資料通路層 DBUtility 資料庫通路元件基礎類 

        其中3中的IDAL對應EnterpriseFrameWork架構中的Dao接口,Model對應架構中的實體,SQLServerDAL和OracleDAL對應不同資料庫Dao;而不同的有5中的DALFactory在架構中是不需要的,隻需配置檔案中配置即可;2中的BLL也職責不一樣,架構中更趨向領域模型的設計;1中的WEB表示層,架構中單獨把Controller控制器分出來獨立一層;是以對比兩者發現其思想還是差别比較大的,個人覺得EnterpriseFrameWork架構除了在程式代碼的解耦,更在業務、項目等實際情況方面更加合适;

接着再讨論一下:貧血模型與充血模型?

貧血模型:是指領域對象裡隻有get和set方法,或者包含少量的CRUD方法,所有的業務邏輯都不包含在内而是放在Business Logic層。

充血模型:層次結構和上面的差不多,不過大多業務邏輯和持久化放在Domain Object裡面,Business Logic(業務邏輯層)隻是簡單封裝部分業務邏輯以及控制事務、權限等。

        對這兩種模型的使用個人感覺比較深刻,以前還不知道這種寫法是貧血模型,表生成所有實體,再就是調用實體的N個邏輯對象,這樣的代碼就越寫越過程化,基本上一個系統分成幾個邏輯對象就完成了,沒有了對象的概念;後來就覺得這樣不對,就把實體擴充成一個完整的業務對象,實作對這個實體的所有業務操作方法;這樣剛開始還蠻有感覺,但後來越做越别扭,一是很多實體根本沒有業務操作,還有就是一個業務操作會跨多個實體;在實體上來補充業務操作方法本來就不太合理,因為表結構的設計本來就不是基于面向對象的;是以後來就演變為現在EnterpriseFrameWork架構中ObjectModel這種模型,我叫做領域對象模型;簡單的業務走第一種模式,複雜的業務就必須分析出領域模型并設計業務對象;

最後分享兩個項目中的小經驗,一個是與大學高校合作開發項目、另一個是小公司老闆的見解;

        與大學高校合作開發一個不算太複雜的項目,公司方負責需求的收集與分析,高校針對需求進行設計與開發;高校由一個研究所學生導師帶隊,也沒用什麼技術架構,就是常用的三層結構,合作的過程就不講了,反正就是最後到我接手維護代碼的時候就感覺到這個系統的坑人之處;首先不算複雜的系統項目建了十多個,找代碼檔案很難找,再就是每改一個小地方要改多個檔案從界面層改到資料層;最受不了的就是代碼的閱讀與調試相當麻煩,每層之間又通過一個工廠反射類名方法名調用;最後我們得出的結論就是在實際項目千萬不能交給高校開發,他們可以搞一些研究項目,做的時候又沒有考慮到一些實際情況;

        小公司老闆的見解。一朋友自己做老闆創業,懂點php網頁開發,在學校招了幾個剛畢業生準備研發一個新産品,要我幫忙他們搭建系統架構,我推薦最早架構給他們使用,那時候在Controller中并沒有OleDB操作資料庫;我先把系統的核心業務開發完成,招的幾個畢業生就在此基礎上繼續完善系統,剛開始我在的時候還好,有什麼不明白的我幫忙解決,後來我抽出來後,他們做着做着問題就暴露出來了,一個簡單的功能很久都搞不出來,新産品講究的就是速度嘛,馬上要給客戶看的;是以朋友急了開始找原因,雖然朋友就會個php網頁制作,但通過與幾個畢業生深入溝通,他發現程式分層太複雜了,做一個功能要畫界面,寫控制器、寫業務對象、寫Dao才能完成,更難的他們根本對邏輯層的控制器、業務對象、Dao了解不了,是以一定要他們這樣用就經常搞出一些莫名其妙的問題;朋友就說為什麼不能直接在控制器中寫sql語句,這樣開發起來多簡單?我就說這樣放開不行,會破壞整個程式的分層結構,以後代碼的維護、擴充都會有問題,但我的這些以後說服不了他,他覺得這些以後版本可以優化,現在就是要馬上出來;最後隻要在控制器也開放了Oledb操作資料庫;

網絡上對于三層結構的解釋:

資料通路層:有時候也稱為是持久層,其功能主要是負責資料庫的通路。簡單的說法就是實作對資料表的Select,Insert,Update,Delete的操作。如果要加入ORM的元素,那麼就會包括對象和資料表之間的mapping,以及對象實體的持久化。在PetShop的資料通路層中,并沒有使用ORM,進而導緻了代碼量的增加,可以看作是整個設計實作中的一大敗筆。

業務邏輯層:是整個系統的核心,它與這個系統的業務(領域)有關。以PetShop為例,業務邏輯層的相關設計,均和網上寵物店特有的邏輯相關,例如查詢寵物,下訂單,添加寵物到購物車等等。如果涉及到資料庫的通路,則調用資料通路層。

表示層:是系統的UI部分,負責使用者與整個系統的互動。在這一層中,理想的狀态是不應包括系統的業務邏輯。表示層中的邏輯代碼,僅與界面元素有關。在PetShop中,是利用ASP.Net來設計的,是以包含了許多Web控件和相關邏輯。

分層的好處

1、開發人員可以隻關注整個結構中的其中某一層;

2、可以很容易的用新的實作來替換原有層次的實作;

3、可以降低層與層之間的依賴;

4、有利于标準化;

5、利于各層邏輯的複用。

概括來說,分層式設計可以達至如下目的:分散關注、松散耦合、邏輯複用、标準定義。

分層的壞處:

1、降低了系統的性能。這是不言而喻的。如果不采用分層式結構,很多業務可以直接造訪資料庫,以此擷取相應的資料,如今卻必須通過中間層來完成。

2、有時會導緻級聯的修改。這種修改尤其展現在自上而下的方向。如果在表示層中需要增加一個功能,為保證其設計符合分層式結構,可能需要在相應的業務邏輯層和資料通路層中都增加相應的代碼。 

繼續閱讀