日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之業(yè)務(wù)邏輯層

一、上章回顧

10年積累的做網(wǎng)站、網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先做網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有象山免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

上章我們主要講述了系統(tǒng)設(shè)計規(guī)范與原則中的具體原則與規(guī)范及如何實現(xiàn)滿足規(guī)范的設(shè)計,我們也講述了通過分離功能點的方式來實現(xiàn),而在軟件開發(fā)過程中的具體實現(xiàn)方式簡單的分為面向過程與面向?qū)ο蟮拈_發(fā)方式,而目前更多的是面向?qū)ο蟮拈_發(fā)設(shè)計方式。并且我們也講述了該如何通過設(shè)計手段去分析功能點及設(shè)計分離點,應(yīng)該如何在設(shè)計的過程中分析的角度及如何去滿足設(shè)計規(guī)范與原則。首先我們通過下圖來回顧下上章要點:

二、摘要

本文將已架構(gòu)的方式去分析分層結(jié)構(gòu)中的業(yè)務(wù)層的設(shè)計,如何寫出來內(nèi)聚度,高耦合的業(yè)務(wù)邏輯層,并且如何根據(jù)我們的項目中的個功能需要去設(shè)計業(yè)務(wù)層。我們本章將會通過幾種可能的業(yè)務(wù)層的設(shè)計模式去分析,并且分析每種設(shè)計模式的優(yōu)點與缺點及每種設(shè)計模式的應(yīng)用場景,并且結(jié)合一定的使用實例來講解,當(dāng)然這些具體的內(nèi)容都是自己在項目中的經(jīng)驗與總結(jié)。錯誤之處,在所難免,本人抱著求真務(wù)實的態(tài)度,爭取寫好每一篇文章,錯誤之處還請大家匹配之處,如果您有好的意見或建議,可以及時跟我溝通,如果對系統(tǒng)架構(gòu)中的設(shè)計規(guī)范與模式不了解,可以點擊這里查看上篇文章:系統(tǒng)架構(gòu)師-基礎(chǔ)到企業(yè)應(yīng)用架構(gòu)-系統(tǒng)設(shè)計規(guī)范與原則[下篇]

本章講解的內(nèi)容我們先看下圖中的幾個簡單模式:

三、本章大綱

1、上章回顧。

2、摘要。

3、本章大綱。

4、業(yè)務(wù)層設(shè)計分析。

5、幾種不同的業(yè)務(wù)設(shè)計模式。

6、本章總結(jié)。

7、系列進(jìn)度。

8、下篇預(yù)告。

四、業(yè)務(wù)層設(shè)計分析

本節(jié)中將會對業(yè)務(wù)層的設(shè)計進(jìn)行詳細(xì)的分析。

首先、我們知道業(yè)務(wù)層是一個系統(tǒng)中最核心的部分,業(yè)務(wù)層是實現(xiàn)系統(tǒng)業(yè)務(wù)功能的核心邏輯層。業(yè)務(wù)層我們通常說的BLL(Business Logic Layer)層,現(xiàn)在我們一般的稍微復(fù)雜一些的業(yè)務(wù)邏輯都是通過分層結(jié)構(gòu)來構(gòu)建一個應(yīng)用系統(tǒng),我想大家在組織業(yè)務(wù)邏輯功能時大部分的情況下是使用BLL層單獨負(fù)責(zé)相應(yīng)的業(yè)務(wù)邏輯來實現(xiàn)的。有些應(yīng)用可能業(yè)務(wù)邏輯層并不復(fù)雜,這是我們可以把問題簡單化,不用引入一些框架性的東西來提升系統(tǒng)的復(fù)雜度,但是有些業(yè)務(wù)規(guī)模較大,并且業(yè)務(wù)邏輯性較強(qiáng)時,可能使用好的業(yè)務(wù)設(shè)計模式帶來的優(yōu)越性就顯而易見了。 我們大家都知道業(yè)務(wù)邏輯層主要是用來處理領(lǐng)域模型對象之間的邏輯關(guān)系的部分。我們都知道業(yè)務(wù)層的數(shù)據(jù)最終是要保存到數(shù)據(jù)庫中,我們在進(jìn)行業(yè)務(wù)層設(shè)計時一般是在架構(gòu)中的分層架構(gòu)模式中出現(xiàn)的。我們知道分層結(jié)構(gòu)中一般是將領(lǐng)域模型與底層數(shù)據(jù)訪問、表現(xiàn)層等進(jìn)行分開組織,這樣可以讓系統(tǒng)結(jié)構(gòu)上清晰,并且容易降低他們之間的耦合性。

其次、其實我們的很多操作都是可以在業(yè)務(wù)層來完成,比如說用戶的角色權(quán)限,數(shù)據(jù)驗證等一些基本的業(yè)務(wù)規(guī)則。當(dāng)然這里說明業(yè)務(wù)層主要負(fù)責(zé)系統(tǒng)中的業(yè)務(wù)規(guī)則的實現(xiàn)。這里我們需要知道2個概念,就是對象模型與領(lǐng)域模型:下面我們說下這2者的區(qū)別。

描述對象模型與領(lǐng)域模型的區(qū)別。

***、業(yè)務(wù)邏輯層作為分層系統(tǒng)中的中間位置,業(yè)務(wù)模型是表現(xiàn)層與數(shù)據(jù)層之間的紐帶。當(dāng)然一般我們在系統(tǒng)設(shè)計時,可能我們一般不會把領(lǐng)域模型中的領(lǐng)域?qū)嶓w作為分層之間的傳輸信息,因為一般來說領(lǐng)域模型中的實體不但包含實體的數(shù)據(jù)信息,并且包含實體的行為??赡芪覀冊诟鲗又兄粫玫綄嶓w的數(shù)據(jù)信息,那么無疑這時采用領(lǐng)域?qū)嶓w的形式進(jìn)行傳輸,那么會增加系統(tǒng)的傳輸負(fù)載。當(dāng)然這里就會出現(xiàn)我們平時所謂的3層模式中的Model層。當(dāng)然Model層設(shè)計的主要作用就是實體數(shù)據(jù)的承載,其中并不包含任何行為。具體的行為通過數(shù)據(jù)訪問層來實現(xiàn)CRUD(DDL中的四個基本操作)的操作。

目前我們設(shè)計的分層結(jié)構(gòu)中的對象模型中并不包含實體的行為。其實這里可以看作是比較好的設(shè)計方式,因為采用對象模型的方式進(jìn)行數(shù)據(jù)傳輸時可以降低系統(tǒng)的耦合。當(dāng)然我們也可以把領(lǐng)域?qū)嶓w看作是多個對象實體的組合并且包含這些對象實體之間的關(guān)系。所以我們在做系統(tǒng)架構(gòu)時可能如何權(quán)衡就比較重要,具體是使用領(lǐng)域?qū)嶓w進(jìn)行數(shù)據(jù)傳輸還是對象實體主要還是看業(yè)務(wù)的需要。

五、幾種不同的業(yè)務(wù)設(shè)計模式

首先我們在業(yè)務(wù)邏輯層設(shè)計時,必須首先確定是采用面向過程還是面向?qū)ο蟮哪J絹碓O(shè)計。 下面我們就將針對開篇介紹的幾種模式進(jìn)行分別介紹,錯誤之處請大家批評指出。我們首先來講解過程式的2類邏輯層的架構(gòu)模式。

過程式模式

1、事務(wù)腳本模式

事務(wù)腳本模式是面向過程的模式,那么我們就不會采用面向?qū)ο蟮脑O(shè)計思想。這種模式是將業(yè)務(wù)代碼映射到用戶的操作中。簡單的理解就是將用戶的每個操作都對應(yīng)一個方法,那么這個方法就是我們這里講的事務(wù)腳本。 當(dāng)然這里的“事務(wù)”就是指我們平時說的業(yè)務(wù)流程,“腳本”則是我們說的流程中的相應(yīng)操作方法。這里

需要注意的是 ,不要認(rèn)為數(shù)據(jù)庫操作的相應(yīng)方法也屬于腳本中的內(nèi)容,我們通常還是將數(shù)據(jù)訪問層單獨的書寫,只不過腳本中調(diào)用而已。通常,事務(wù)腳本模式中都是一系列的邏輯判定或者循環(huán)或其他方式,通過一系列的函數(shù)調(diào)用來實現(xiàn)業(yè)務(wù)流程的。通常來說一般業(yè)務(wù)比較單一或者不是很復(fù)雜的系統(tǒng)功能,通過該模式實現(xiàn)起來會比較簡單。而且如果業(yè)務(wù)流程中的變化較為頻繁的話不建議使用該模式來做。我們認(rèn)為,我們對于這類簡單的功能,我們沒有必要花費(fèi)較大的代價去設(shè)計領(lǐng)域模型和其他方面的考慮。事務(wù)腳本模式的一大優(yōu)勢就是很簡單,沒有開始時的額外代價,它可以很好的進(jìn)行快速的應(yīng)用程序開發(fā),一般情況下來說,如果一個項目的時間緊迫,邏輯簡單,并且使用強(qiáng)大的開發(fā)工具時,我們可以使用這樣的模式來進(jìn)行,無論是成本還是開發(fā)效率上都非??陀^。

我們根據(jù)上面的介紹可能認(rèn)為,事務(wù)腳本模式的可重用性不高,并且耦合性太高,適應(yīng)性并不好,當(dāng)時我們?nèi)匀豢梢酝ㄟ^我們好的設(shè)計來實現(xiàn)代碼的重用,我們可以在進(jìn)行“腳本”編寫時將重用的部分抽象出來,寫一個單獨的函數(shù),以達(dá)到復(fù)用的目的。事務(wù)腳本模式的一個重大缺點就是通過這樣的設(shè)計很容易造成代碼重復(fù),通常來說我們很容易完成一系列的業(yè)務(wù)功能,但是隨著應(yīng)用程序功能的增加,那么應(yīng)用程序代碼會變成非常復(fù)雜的程序結(jié)構(gòu),當(dāng)然我們可以通過重構(gòu)去環(huán)節(jié)該模式的這一劣勢,當(dāng)規(guī)模達(dá)到一定程度時,我們同樣沒辦法去完成重構(gòu)工作。

通過上面的講述,我們對事務(wù)腳本模式有了初步的認(rèn)識,那么下來我們看看我們在進(jìn)行業(yè)務(wù)邏輯層設(shè)計時的詳細(xì)使用該模式的步驟及相關(guān)準(zhǔn)則。

本圖描述了事務(wù)腳本模式的設(shè)計過程,那么基本上每個系統(tǒng)流程都可以通過這樣的流程來完成設(shè)計。下面我們就針對一個簡單的實例來講解下

如何通過這樣的設(shè)計流程來實現(xiàn)系統(tǒng)的功能。

我們這里以簡單的購物流程來講述。如何下一個訂單

首先、我們先來分析下用例:

我們知道注冊的會員可以通過將產(chǎn)品添加到購物車中,然后通過去付款模塊來進(jìn)入支付系統(tǒng),完成訂單。

其次、分析出事務(wù)。

一般來說購物的流程是這樣的流程。當(dāng)然這里也不是標(biāo)準(zhǔn)的形式。

那么我們?nèi)绾紊鲜龅膸讉€步驟的內(nèi)容,去完成這個事務(wù)的流程。

 
 
 
 
  1. public class BuyInfo  
  2.   {  
  3.   ///   
  4.   /// 購物車中的產(chǎn)品列表  
  5.   ///   
  6.  private List proList = new List();  
  7.   public int CreateBuyCar(Product product)  
  8.   {  
  9.  //事務(wù)開始  
  10.   this.BeginTranstion();  
  11.   //判定當(dāng)前添加到購物車中的產(chǎn)品信息是否是自己發(fā)布的產(chǎn)品  
  12.   if (!this.IsCanBuy(product.PutOutID))  
  13.   return;  
  14.   //判定當(dāng)前產(chǎn)品的庫存信息是否大于當(dāng)前購買的數(shù)量;  
  15.   if(!this.IsLagerThenBuy(product.PutOutID))  
  16.   return;  
  17.   //添加產(chǎn)品到購物車  
  18.   proList.Add(product);  
  19.   //處理生成訂單信息  
  20.   int orderID= this.CreateOrder();  
  21.   //事務(wù)結(jié)束  
  22.   this.EndTranstion();  
  23.   return orderID;  
  24.   }  
  25.   ///   
  26.   /// 生成訂單  
  27.   ///   
  28.   ///   
  29.   private int CreateOrder()  
  30.   {  
  31.   Order order = new Order(this);  
  32.   return order.CreateOrder();  
  33.   }  
  34.   ///   
  35.   /// 判定當(dāng)前產(chǎn)品的庫存信息是否大于當(dāng)前購買的數(shù)量  
  36.   ///   
  37.   ///   
  38.   ///   
  39.   private bool IsLagerThenBuy(int p)  
  40.   {  
  41.   return false;  
  42.   }  
  43.   ///   
  44.   /// 判定是否是自己發(fā)布的產(chǎn)品信息  
  45.   ///   
  46.   ///   
  47.   private bool IsCanBuy(int p)  
  48.   {  
  49.   return false;  
  50.   }  
  51.   private void EndTranstion()  
  52.   {  
  53.   //TODO..  
  54.   }  
  55.   private void BeginTranstion()  
  56.   {  
  57.   //TODO..  
  58.   }  
  59.   } 

這里定義的是添加到購物車的流程,下面將給出如何將購物車中的產(chǎn)品信息添加到訂單中的具體流程。

 
 
 
 
  1.   public class Order  
  2.   {  
  3.   private BuyInfo info;  
  4.   public Order(BuyInfo buyInfo)  
  5.   {  
  6.   info = buyInfo;  
  7.   }  
  8.   public int CreateOrder()  
  9.   {  
  10.   //將BuyInfo購物車中的產(chǎn)品列表與訂單信息進(jìn)行關(guān)聯(lián)。  
  11.   this.InitOrderInfo();  
  12.   //將訂單中的會員信息關(guān)聯(lián)  
  13.   this.InitOrderUserInfo();  
  14.   //將訂單中的收貨信息關(guān)聯(lián)。  
  15.   this.InitOrderReciveInfo();  
  16.   //將訂單中的支付信息關(guān)聯(lián)。  
  17.   this.InitOrderPayInfo();  
  18.   //生成訂單。  
  19.   }  
  20.   ///   
  21.   /// 將購物車中的產(chǎn)品添加到數(shù)據(jù)庫中  
  22.   ///   
  23.   private void InitOrderInfo()  
  24.   {  
  25.   throw new NotImplementedException();  
  26.   }  
  27.   ///   
  28.   /// 初始化訂單的支付信息  
  29.   ///   
  30.   private void InitOrderPayInfo()  
  31.   {  
  32.   throw new NotImplementedException();  
  33.   }  
  34.   ///   
  35.   /// 初始化訂單中的收貨信息  
  36.   ///   
  37.   private void InitOrderReciveInfo()  
  38.   {  
  39.   throw new NotImplementedException();  
  40.   }  
  41.   ///   
  42.   /// 初始化訂單的買家信息  
  43.   ///   
  44.   private void InitOrderUserInfo()  
  45.   {  
  46.   throw new NotImplementedException();  
  47.   }  
  48.   } 

通過上面的形式基本上就完成了簡單事務(wù)腳本模式的構(gòu)建,當(dāng)然我們也可以將所有的一系列的腳本封裝到一個類里面,通過靜態(tài)方法的方式來訪問也是可以的。只是組織方法的形式不同。當(dāng)然我這里提高了,通過將腳本封裝到一個類里面,通過靜態(tài)方法的形式或者實例方法的形式都是可以的,那么我們來講講什么時候封裝成靜態(tài)方法,什么時候封裝成實例方法。

我們?nèi)绾螌?shù)據(jù)傳入給實體腳本呢,通常我們是通過前面我們說的對象實體來完成的,因為數(shù)據(jù)對象實體只是包含實體的數(shù)據(jù)信息,并不包含具體的行為。

那么我們來簡單說說對象實體中的信息及格式,我想大家用過分層結(jié)構(gòu)中的Model層的都會比較的清楚,下面我們看看,不詳細(xì)介紹了:

 
 
 
 
  1.   public class Product  
  2.   {  
  3.   private int putoutID;  
  4.   public int PutOutID  
  5.   {  
  6.   get 
  7.   {  
  8.   return this.putoutID;  
  9.   }  
  10.   set 
  11.  {  
  12.   this.putoutID = value;  
  13.   }  
  14.   }  
  15.   private int productID;  
  16.   public int ProductID  
  17.   {  
  18.   get 
  19.   {  
  20.   return this.productID;  
  21.   }  
  22.   set 
  23.   {  
  24.   this.productID = value;  
  25.   }  
  26.   }  
  27.   private int productName;  
  28.   public int ProductName  
  29.   {  
  30.   get 
  31.   {  
  32.   return this.productName;  
  33.   }  
  34.   set 
  35.   {  
  36.   this.productName = value;  
  37.   }  
  38.   }  
  39.  private int productUnit;  
  40.   public int ProductUnit  
  41.   {  
  42.   get 
  43.   {  
  44.   return this.productUnit;  
  45.   }  
  46.   set 
  47.   {  
  48.   this.productUnit = value;  
  49.   }  
  50.   }  
  51.   private int productClass;  
  52.   public int ProductClass  
  53.   {  
  54.   get 
  55.   {  
  56.   return this.productClass;  
  57.   }  
  58.   set 
  59.   {  
  60.   this.productClass = value;  
  61.   }  
  62.   }  
  63.   } 

我們看到了主要是通過get;set訪問器來實現(xiàn)的。

總結(jié):業(yè)務(wù)邏輯層是將表現(xiàn)層觸發(fā)一系列事務(wù)分別實現(xiàn),那么對業(yè)務(wù)邏輯層的建模其實就是對事務(wù)的具體實現(xiàn),將事務(wù)映射到業(yè)務(wù)邏輯層中的不同方法上,一般來說事務(wù)代碼維護(hù)起來比較難以維護(hù),重用性低,難以理解。

2、表模塊模式

表模塊模式是對事務(wù)腳本模式的實踐總結(jié)并優(yōu)化而提出的新模式。相比而言,表模塊模式結(jié)構(gòu)性更強(qiáng),總體來說,表模塊就是就是將數(shù)據(jù)庫中的某個表上的所有可能的操作都寫在一個類文件中,這個類文件中定義了該數(shù)據(jù)庫表對應(yīng)的所有的業(yè)務(wù)方法。表模塊類是一個容器,它內(nèi)部包含了類的數(shù)據(jù)信息和相應(yīng)的行為。表模塊是映射數(shù)據(jù)庫表的關(guān)系,因此表模塊對應(yīng)的是數(shù)據(jù)集合,那么無法將數(shù)據(jù)庫表中的某個行記錄進(jìn)行區(qū)分,只能通過集合中的鍵或者索引來訪問行記錄的信息。

表模塊模式由于是在事務(wù)腳本模式發(fā)展的更有結(jié)構(gòu)化的模式,那么可以說表模塊模式雖然是面向過程的模式,但是它朝面向?qū)ο蟮哪J揭呀?jīng)邁了很大的一步,我們知道,在將對象模型中的數(shù)據(jù)保存到關(guān)系數(shù)據(jù)庫中時,需要使用相關(guān)的ORM工具去完成相應(yīng)的轉(zhuǎn)換。我們知道面向?qū)ο竽P湍軌蚝莒`活、更好的對領(lǐng)域模型建模。當(dāng)然,表模塊模式仍然關(guān)注的是方法,而不是對象。

通常我們在更好的結(jié)構(gòu)設(shè)計指導(dǎo)的同時,那么我們需要考慮更多的規(guī)則,那么意味著我們需要書寫更多的代碼。表模塊模式的具體實例可以參考Visio Studio中的提供的DataSet和dataTable。表模塊在處理簡單的實體時具有很好的優(yōu)勢,但是當(dāng)實體較復(fù)雜時,或者實體之間的關(guān)系緊密時無法很好的處理。下面我們來看看一個簡單的例子來說明表模式的使用。我們這里還是以剛才事務(wù)模型中的購買流程來講解。

數(shù)據(jù)庫表與表模塊類的映射關(guān)系是通過.NET提供的內(nèi)存數(shù)據(jù)對象DataSet、

DataTable來實現(xiàn)。

 
 
 
 
  1.   public class Order  
  2.   {  
  3.   private System.Data.DataTable _orderItems;  
  4.   private DataSet _ds;  
  5.   public Order(DataSet ds)  
  6.   {  
  7.   _ds = ds;  
  8.   }  
  9.   ///   
  10.   /// 返回訂單對應(yīng)的所有產(chǎn)品信息  
  11.   ///   
  12.   ///   
  13.  public DataTable Products()  
  14.   {  
  15.   return _orderItems;  
  16.   }  
  17.   ///   
  18.   /// 返回當(dāng)前索引號的訂單信息  
  19.   ///   
  20.   ///   
  21.   ///   
  22.   public DataRow GetRow(int index)  
  23.   {  
  24.   return _ds.Tables[0].Rows[index];  
  25.   }  
  26.   ///   
  27.   /// 根據(jù)訂單的ID返回訂單的信息  
  28.   ///   
  29.   ///   
  30.   ///   
  31.   public DataRow GetRowByID(int id)  
  32.   {  
  33.   return _ds.Tables[0].Select("id=" + id.ToString());  
  34.   }  
  35.   public int Update(int orderID)  
  36.   {  
  37.   return 0;  
  38.   }  
  39.   public int Delete(int orderID)  
  40.   {  
  41.   return 0;  
  42.  }  
  43.   public int Insert(int orderID)  
  44.   {  
  45.   return 0;  
  46.   }  
  47.  } 

我們這里的數(shù)據(jù)如果發(fā)生變化時,我們?nèi)绾螌⒆兓说膬?nèi)存中的datatable或者dataset持久化到數(shù)據(jù)庫中呢,ADO.NET為我們提供了dataadapter,通過這個適配器我們完成datatable中的數(shù)據(jù)持久化到數(shù)據(jù)庫表中。具體的形式就是上圖中的流程,UI層通過數(shù)據(jù)請求方法,然后表模塊層中有相應(yīng)的方法,將發(fā)送數(shù)據(jù)請求訪問數(shù)據(jù)庫,然后數(shù)據(jù)庫返回相應(yīng)結(jié)果通過datatable或dataset來初始化表模塊類中的數(shù)據(jù)信息,然后返回給UI層相應(yīng)的數(shù)據(jù)信息,然后綁定后顯示。

總結(jié):表模塊模式相比事務(wù)腳本模式。是我們推薦的使用模式。并且VS中自動繼承了相應(yīng)的datatable 與datas的相應(yīng)的圖形化設(shè)計方法,很方便的使用。并且內(nèi)部.NET framework 內(nèi)置了相應(yīng)的操作方法可以迅速的實現(xiàn)交互,在過程式模式中無疑是使用表模塊模式是***方案。表模塊模式更關(guān)注的是與數(shù)據(jù)庫表的映射關(guān)系,那么可以說表模塊模式中包含了數(shù)據(jù)模型。有一些面向?qū)ο蟮奈兜?,不過表模塊模式中并不關(guān)注業(yè)務(wù)。

對象式模式

我們來講述下面向?qū)ο蟮哪J街械?種方案

1、活動記錄模式

我們知道業(yè)務(wù)邏輯層中的業(yè)務(wù)邏輯才是系統(tǒng)的核心,那么我們更關(guān)注的是業(yè)務(wù)邏輯或者領(lǐng)域邏輯。因為我們必須關(guān)系實體之間的交互。我們?nèi)绻麑︻I(lǐng)域模型建模。我們需要使用面向?qū)ο蟮慕嵌热シ治鲂枨蟆?我們先來看看基于對象模式的活動記錄模式。

活動記錄模式是在表模塊模式的基礎(chǔ)上,將表模塊的粗粒度的基于數(shù)據(jù)集上的映射細(xì)化到表中行記錄的細(xì)粒度的映射,并且映射的對象中包含相應(yīng)的數(shù)據(jù)庫表中的數(shù)據(jù)信息,并且包含對象的行為。例如,我們現(xiàn)在如果想將產(chǎn)品表中的產(chǎn)品信息映射到數(shù)據(jù)庫中的表product中的行記錄,那么我們需要構(gòu)建一個product類,該類中的屬性與product表中的列信息一一對應(yīng)。并且product類中還包含該對象所有的行為。例如CRUD的操作,其他的行為等。

首先我們需要知道活動記錄的優(yōu)勢是什么?首先我的理解就是活動記錄模式容器理解,簡單,并且目前有很多的框架支持這樣的模式。首先就像Linq、Castle框架都是采用這樣的模式。。一般情況下,活動記錄模式在關(guān)系型模型中可以很好的支持。如果在應(yīng)用程序中不使用關(guān)系型模型來設(shè)計業(yè)務(wù)層的話,那么需要我們?nèi)斯斫M織,協(xié)調(diào)活動記錄與數(shù)據(jù)模型之間,其實這個就可以簡單的理解為數(shù)據(jù)映射,一般的ORM框架中都提供這樣的功能。

我們需要知道,如果活動記錄模式下的對象發(fā)生改變了,那么數(shù)據(jù)庫也得跟著修改,或者數(shù)據(jù)庫表發(fā)生改變了,那么你不得不修改對應(yīng)的活動記錄對象及相關(guān)代碼。

總而言之,如果我們在使用活動記錄模式的過程中如果不能保證對象模型與數(shù)據(jù)模型之間的對應(yīng)關(guān)系,那么我們將會很快失控,那么領(lǐng)域模型顯然能夠解決這樣的問題。下面我們來看下活動記錄模式的實例。我們還是以購物流程為例。

 
 
 
 
  1.   public class Order  
  2.   {  
  3.   private int _orderID;  
  4.   public Order(int orderID)  
  5.   {  
  6.   _orderID = orderID;  
  7.   }  
  8.   public int OrderID  
  9.   {  
  10.   get 
  11.  {  
  12.   return this._orderID;  
  13.   }  
  14.   set 
  15.   {  
  16.   this._orderID = value;  
  17.  }  
  18.   }  
  19.   private int _orderState;  
  20.   public int OrderState  
  21.   {  
  22.   get 
  23.   {  
  24.   return this._orderState;  
  25.   }  
  26.   set 
  27.   {  
  28.   this._orderState = value;  
  29.   }  
  30.   }  
  31.   ///   
  32.   /// 返回訂單對應(yīng)的所有產(chǎn)品信息  
  33.   ///   
  34.   ///   
  35.   public List Products()  
  36.   {  
  37.   return this.GetProducts();  
  38.   }  
  39.   private List GetProducts()  
  40.   {  
  41.   List lists = new List();  
  42.   return lists;  
  43.   }  
  44.   public int Update()  
  45.   {  
  46.   return 0;  
  47.   }  
  48.   public int Delete()  
  49.   {  
  50.   return 0;  
  51.   }  
  52.   public int Insert()  
  53.   {  
  54.   return 0;  
  55.   }  
  56.   } 

我們可以看到區(qū)別,從原來的表模式中的通過ADO.NET提供的內(nèi)存集合表中的形式,修改為通過對象中的屬性的形式來保存對象的數(shù)據(jù)信息,顯然這就是表模式與活動記錄模式的***區(qū)別。不過實現(xiàn)的思想上差別不大。

我們都知道數(shù)據(jù)庫表之間如果有關(guān)聯(lián)的話,那么我們通過的是外鍵的形式來進(jìn)行關(guān)聯(lián),那么我們在活動記錄中一般如何來標(biāo)識某個類對應(yīng)的外鍵對象信息呢。

那么我們在訂單中可能會有對應(yīng)的用戶ID,不過在不同的框架中可能對外鍵對應(yīng)的對象信息的存儲方式會有所不同,有些框架中在外鍵對象上通過屬性的方式返回對象的實例的應(yīng)用。簡單來說下這2種方式的區(qū)別:例如:

 
 
 
 
  1.   public class Order  
  2.   {  
  3.   private int _orderID;  
  4.   public Order(int orderID)  
  5.   {  
  6.   _orderID = orderID;  
  7.   }  
  8.   public int OrderID  
  9.   {  
  10.  get 
  11.   {  
  12.   return this._orderID;  
  13.   }  
  14.   set 
  15.   {  
  16.   this._orderID = value;  
  17.   }  
  18.   }  
  19.   private int _orderState;  
  20.   public int OrderState  
  21.   {  
  22.   get 
  23.   {  
  24.   return this._orderState;  
  25.   }  
  26.   set 
  27.   {  
  28.   this._orderState = value;  
  29.  }  
  30.   }  
  31.   private int _userID;  
  32.   public int UserID  
  33.   {  
  34.   get 
  35.   {  
  36.   return this._userID;  
  37.  }  
  38.   set 
  39.   {  
  40.   this._userID=value;  
  41.   }  
  42.   }  
  43.  } 

另外一種形式。直接將User用戶的完整對象引用實例返回。

 
 
 
 
  1.   public class Order  
  2.   {  
  3.   private int _orderID;  
  4.   public Order(int orderID)  
  5.   {  
  6.   _orderID = orderID;  
  7.   }  
  8.   public int OrderID  
  9.   {  
  10.   get 
  11.   {  
  12.   return this._orderID;  
  13.   }  
  14.   set 
  15.   {  
  16.   this._orderID = value;  
  17.   }  
  18.   }  
  19.   private int _orderState;  
  20.   public int OrderState  
  21.   {  
  22.   get 
  23.   {  
  24.   return this._orderState;  
  25.   }  
  26.   set 
  27.   {  
  28.   this._orderState = value;  
  29.   }  
  30.   }  
  31.   private UserInfo _userinfo;  
  32.   public UserInfo User  
  33.   {  
  34.   get 
  35.   {  
  36.   return this._userinfo;  
  37.   }  
  38.   set 
  39.   {  
  40.   this._userinfo=value;  
  41.   }  
  42.   }  
  43.  } 

上面我們看到了活動記錄模式的簡單使用方式,當(dāng)然我這里沒有說是寫出來可以運(yùn)行的實例代碼。只是簡單的顯示了,使用這些模式可能的用法,當(dāng)然如果大家有更好的理解或者用法可以一起交流。當(dāng)然活動記錄模型一般就能滿足我們的系統(tǒng)功能,如果說針對業(yè)務(wù)復(fù)雜的領(lǐng)域,那么必須設(shè)計領(lǐng)域模型去完成相應(yīng)的業(yè)務(wù)邏輯層的設(shè)計。下面我們將來介紹領(lǐng)域模型模式的相關(guān)實例。

2、領(lǐng)域模型模式

我們前面講解的幾類模式,其實說白了都是以數(shù)據(jù)為中心進(jìn)行抽象與設(shè)計的形式,當(dāng)然采用這樣的形式無疑是以業(yè)務(wù)中的數(shù)據(jù)為中心,并不是關(guān)心的業(yè)務(wù)本身。以數(shù)據(jù)為核心的設(shè)計方法一般流程如下:

一般來說我們目前主流的方式都是這樣的順序來執(zhí)行。當(dāng)然通過這樣的方式的確一般的簡單應(yīng)用當(dāng)然都是沒有太大的問題。有的時候我們需要同時關(guān)系對象的數(shù)據(jù)與行為,那么顯然以數(shù)據(jù)為核心的情況就會顯得力不從心,當(dāng)然簡單的系統(tǒng)時不會有太大的體現(xiàn),當(dāng)時當(dāng)系統(tǒng)的規(guī)模上升到一定的程度時,哪怕添加一些新的需求時,對系統(tǒng)的影響都是致命的。

領(lǐng)域模型關(guān)注的是系統(tǒng)期待的行為及系統(tǒng)正常工作所需要的數(shù)據(jù)流。一般我們在設(shè)計領(lǐng)域模型的時候需要這個領(lǐng)域的專家協(xié)助,***以類的形式呈現(xiàn)出來。當(dāng)然

領(lǐng)域模型模式中的實現(xiàn)方式,大家都知道的就是有名的DDD(領(lǐng)域驅(qū)動設(shè)計)。

領(lǐng)域模型設(shè)計的最終目標(biāo)就是與系統(tǒng)的概念模型匹配起來。我們可以把領(lǐng)域模型看作是概念模型的物理模型。在一個項目中可以說領(lǐng)域模型是最重要的,最關(guān)鍵的部分。

領(lǐng)域模型可以看作是一系列對象之間的交互。領(lǐng)域模型中的每一部分都需要用一個帶有行為的類來表示。這個怎么理解呢,請看圖:

訂單信息對象首先會與訂單中的產(chǎn)品對象有交互關(guān)系,產(chǎn)品項與產(chǎn)品分類有交互關(guān)系。訂單信息與用戶買家有交互關(guān)系,訂單的其他信息(物流信息、支付信息等)有交互關(guān)系。

例如我們常說的記錄的系統(tǒng)日志,不管是錯誤日志還是其他的所有系統(tǒng)中的日志,那么我們建議的方式采用AOP的方式來處理。那么我們來看看具體的代碼實現(xiàn):

 
 
 
 
  1.   //定義接口  
  2.   public interface ILog  
  3.   {  
  4.   //具體的寫日志的方法  
  5.   void WriteLog();  
  6.   }  
  7.   //簡單實現(xiàn)  
  8.   public class BaseWrite : ILog  
  9.   {  
  10.   #region ILog 成員  
  11.   ///   
  12.   /// 基本的書寫日志的方法  
  13.   ///   
  14.   public void WriteLog()  
  15.   {  
  16.   try 
  17.   {  
  18.   Write.WriteLog(this);  
  19.   }  
  20.   catch 
  21.   {  
  22.   }  
  23.   }  
  24.   #endregion  
  25.   } 

具體調(diào)用的寫日志的方法:

 
 
 
 
  1.   public class Write  
  2.   {  
  3.   public static bool WriteLog(ILog log)  
  4.   {  
  5.   //具體的寫如日志的方法。  
  6.   return true;  
  7.   }  
  8.   }  
  9.   具體相關(guān)的產(chǎn)品類與產(chǎn)品分類對象的使用:  
  10.   ///   
  11.   /// 產(chǎn)品類  
  12.   ///   
  13.   public class Product : BaseWrite  
  14.   {  
  15.   //產(chǎn)品的相關(guān)屬性  
  16.   public int ProductID { get;set;}  
  17.   public int ProductName { get;set;}  
  18.   public int ProductClassID { get;set;}  
  19.   public int ProductSort { get;set;}  
  20.   public int ProductIsEnable { get;set;}  
  21.   //產(chǎn)品類相關(guān)的方法  
  22.   public List GetAll()  
  23.   {  
  24.   return new List();  
  25.   }  
  26.   }  
  27.   public class ProductClass : BaseWrite  
  28.   {  
  29.   //產(chǎn)品分類相關(guān)屬性  
  30.   public int ProductClassID { get;set;}  
  31.   public int ProductClassName { get;set;}  
  32.  public int ProductClassCategory { get;set;}  
  33.   public int ProductClassSort { get;set;}  
  34.   public int ProductClassIsEnable { get;set;}  
  35.  //產(chǎn)品分類相關(guān)的信息  
  36.   public List GetAll()  
  37.   {  
  38.   return new List();  
  39.   }  
  40.   } 

我們看到了在活動記錄模式中會將數(shù)據(jù)訪問層的代碼寫在該層,但是領(lǐng)域模型中一般不會出現(xiàn)這樣的代碼。領(lǐng)域模型中只關(guān)心跟業(yè)務(wù)流程相關(guān)的內(nèi)容,具體的數(shù)據(jù)持久化之類的內(nèi)容一概不關(guān)心。領(lǐng)域模型中是一系列的對象之間的交互,那么我們可能會關(guān)心,如何將領(lǐng)域模型中的這些對象的狀態(tài)進(jìn)行保存呢,那么就會牽扯到對象模型到關(guān)系型數(shù)據(jù)庫中持久化的個問題了,在持久化的問題上,我們可能有幾種選擇,一種是采用現(xiàn)有的ORM框架去實現(xiàn)對象數(shù)據(jù)的自動持久化,當(dāng)然這是一種解決辦法。有時候我們是通過手動的方式來進(jìn)行持久化,可能就不存在這樣的問題。

我們通常在持久化數(shù)據(jù)的問題上我們希望能做到持久化的透明性,這樣就可以說具體的業(yè)務(wù)層不需要書寫持久化的操作代碼,當(dāng)然我們現(xiàn)在設(shè)計的時候可能都是要么是通過特性來實現(xiàn)持久化,或者是通過繼承基類的方式來做持久化的操作,那么可能帶來如下的問題。

一般我們知道,一個類如果想不寫相應(yīng)的持久化代碼還能實現(xiàn)持久化的話,那么我們只能通過動態(tài)的注入持久化代碼的方式來實現(xiàn)這樣的持久化透明的方案,微軟的EntityFrameWork2.0中的POCO中的ORM方案,就是通過這樣的方式來實現(xiàn)的。我們更關(guān)心的是代碼應(yīng)該放在何處,是在領(lǐng)域模型中還是領(lǐng)域模型外呢,當(dāng)然目前的一些常見的框架中已有實現(xiàn)方案,其中大家熟知的NHibernate就是持久化透明的方式,大家如果感興趣可以參考NHibernate的實現(xiàn)思路來做。一般對于這種動態(tài)注入代碼的這樣的方案,這里簡單介紹下可能的實現(xiàn),由于.NET framework 中提供了一個派生自特性類型的代理類,通過代理類來動態(tài)的將這個類的相關(guān)功能追加到指定的對象中,這就是所謂的動態(tài)代理,當(dāng)然針對某個特定的類型這樣來做,WCF也是通過代理類的方式來實現(xiàn)這樣的動態(tài)插入的形式。

六、本章總結(jié)

本章主要是對業(yè)務(wù)層建模的不同的架構(gòu)模式進(jìn)行了相應(yīng)的總結(jié)及簡單說明,可能某些地方說明不是特別的清晰,當(dāng)然我也是將平時自己的業(yè)務(wù)開發(fā)中的一些經(jīng)驗和總結(jié),部分內(nèi)容是參考以前看的書上的內(nèi)容,不足之處還請大家多多的指點,還有請感興趣的朋友一起交流領(lǐng)域模型的設(shè)計,包括持久化的透明的實現(xiàn)方案等,歡迎大家多提意見和建議。本人抱著學(xué)習(xí)和寧缺毋濫的原則,寫好每一篇,可能看過這方面資料的同仁當(dāng)溫習(xí)下相關(guān)內(nèi)容,沒有看過同仁希望對你們有幫助,那就是我***的動力。

八、下篇預(yù)告

下一篇我們將會開始講解軟件設(shè)計中最重要也是最基本的技能-設(shè)計模式,希望大家多多提出已經(jīng),后面3篇我們將會講解如何在項目中使用設(shè)計模式及使用設(shè)計

模式需要注意的事項,將會舉例說明每個設(shè)計模式可能出現(xiàn)的場景。希望大家持續(xù)關(guān)注!

作者:CallHot-何戈洲

出處:http://www.cnblogs.com/hegezhou_hot/

關(guān)于作者:專注于微軟平臺項目架構(gòu)、管理和企業(yè)解決方案。熟悉設(shè)計模式、極限編程、架構(gòu)設(shè)計、敏捷開發(fā)和項目管理?,F(xiàn)主要從事WinForm、ASP.NET、等方面的項目開發(fā)、架構(gòu)、管理工作。如有問題或建議,請多多賜教!

【編輯推薦】

  1. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之開卷有益
  2. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模1
  3. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模2
  4. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模3
  5. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)建模4
  6. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計規(guī)范與原則1
  7. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之系統(tǒng)設(shè)計規(guī)范與原則2
  8. 系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之業(yè)務(wù)邏輯層

網(wǎng)頁標(biāo)題:系統(tǒng)架構(gòu)師談企業(yè)應(yīng)用架構(gòu)之業(yè)務(wù)邏輯層
標(biāo)題路徑:http://www.dlmjj.cn/article/cdiodjo.html