天天看點

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

接下來,将說明如何進行代碼轉換,使用 rafy 來開發一個典型的資料庫應用程式。(以下内容拷貝自示例包中的 pdf 文檔。)

考慮到要更好地示範如何使用 rafy 架構來開發一個傳統的管理系統,決定挑選一個開源系統進行改造,而這個系統應該是簡單、常見的三層架構,這種系統大家都比較熟悉,這樣就可以更加快速的了解架構的使用了。

系統功能描述:

人員:操作員管理,供應商管理,顧客管理

庫存:庫存管理,庫存盤點

銷售:服裝銷售,服裝退貨

服裝:服裝類别,服裝登記

銷售:銷售統計,利潤統計

技術特點:使用了三層架構設計程式,更換底層資料庫類型友善。系統使用了 sqllite 作為資料庫,下載下傳後可以直接運作。

界面截圖 :

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

原系統是簡單的三層架構:

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

而我們會使用 rafy 推薦的架構,來改造整個系統:

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

對于一個依賴關系較為嚴格的三層系統來說,要使用 rafy 架構來替換其中的資料通路層、業務邏輯層以及界面查詢的功能,是比較簡單的。本次轉換,我按照以下步驟進行:

1. 了解系統需求,使用 uml 畫出領域實體間的關系。

2. 添加 rafy 領域實體項目。

3. 根據實體的關系圖,在實體程式集中添加對應的實體及實體間的關系;同時也可以把舊表中的屬性添加到實體中。

4. 把所有跨多表的業務邏輯轉換為領域服務。

5. 依次把曆史的實體删除,轉而使用新的 rafy 實體,以及其對應的實體查詢、領域服務。

接下來,就正式對代碼進行轉換:

經分析,原系統擁有以下領域模型:

user:使用者;

company:供應商;

customer:顧客;

goodcategory:商品類别;

good:商品(服裝);

stock:入庫資訊;

regood:返庫資訊;

bill 及 sell:銷售單據及銷售明細。

它們的關系如下:

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

(雖然原系統中一些實體的名稱取得并不合理,但是為了簡化系統的轉換工作,新系統中的類命名還是保持和原系統一緻。)

關于哪些關系應該使用組合關系來進行設計,大家可以檢視 rafy 使用者向導文檔中的“領域實體架構/領域實體/實體關系”章節。

在開始轉換代碼前,由于原程式使用的是 .net 2.0 的運作時,而 rafy 要求必須使用 .net 4.0。是以我們需要把解決方案中的每個項目都轉換為 .net 4.0 版本。

需要注意的是,由于原程式使用的 sqllite 隻支援 2.0 版本。同時,需要把 sqllite 替換為 .net 4.0 的版本。

在解決方案中添加一個 rafy 領域實體項目,命名為 cs(為原系統名 clothessys 的縮寫)。

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式
Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

點選确定後生成的項目如下:

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

接下來,我們将會在這項目中添加領域實體與領域服務,來替換原程式中除界面項目以外的其它幾個項目:

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

接下來,依次把曆史的實體删除,轉而使用新的 rafy 實體。這一步,需要按照依賴關系,盡量先轉換不依賴其他實體的實體,即按照以下順序進行轉換:user、company、customer、goodcategory、good、stock、regood、bill 和 sell。由于 bill 和 sell 有強聚合關系,是以放到最後一起轉換。

(在變更每一個實體時,原代碼中所有的 bll 查詢,都需要在實體倉庫中編寫相關的代碼支援;業務邏輯則需要編寫領域服務)

實體的轉換分為以下幾類:

無關系實體的轉換

有關系實體的轉換

組合實體的轉換

簡單實體沒有複雜的關系,隻是映射一個簡單的表。在轉換為 rafy 實體時,隻需要把表中的所有屬性都添加到實體中就可以了。在編寫時,需要注意的是:

辨別

轉換為 rafy 實體後,所有的實體都統一繼承自 entity 類型。entity 類聲明了 int 類型的 id 屬性作為所有實體的辨別屬性,這個屬性會在資料庫中生成一個自增長的主鍵列。

舊實體類上的所有主鍵列、唯一列,在新實體中都變成了普通列。實體屬性的唯一性驗證,需要放到實體之上的業務邏輯層中來完成。

屬性

原實體的所有屬性,在 rafy 實體中都使用屬性代碼段來生成同名的實體屬性代碼即可。

轉換查詢資料的代碼

在原代碼中 bll、dal 兩層中,都有許多的查詢方法。這些方法都需要轉換為新代碼中對應實體的實體倉庫中的查詢方法。例如,原程式中通過顧客編号查詢顧客的查詢方法:

需要轉換為 rafy 實體倉庫中的新方法:

轉換業務邏輯代碼

bll、dal 中,除了查詢方法以外,剩下的還有一些簡單對實體的增、删、改操作。這些操作已經在實體倉庫基類中實作了,是以可以不用轉換。

除了簡單的 crud 操作外,系統中還有一些需要同時操作多個表的事務操作,原系統把這些業務邏輯都寫到了資料層中。例如 regoodservice.regoodsumbit 方法:

可以看到,這段代碼中,不但有業務邏輯的控制,還有資料庫連接配接的控制,事務的控制,sql 語句的拼裝。顯得非常混亂。而這種業務邏輯,在 rafy 架構中,可以使用領域服務來實作。例如,剛才的邏輯,被替換為以下代碼:

可以看到,使用 rafy 領域服務來實作後有以下好處:

整個代碼非常直接地表現了業務邏輯,沒有一點多餘的代碼。

使用了引用實體屬性的懶加載功能,使得程式可以直接使用如 regood.sell.customer 這樣的強引用關系。

友善通用代碼的封裝。例如,事務的控制已經交給了服務基類來處理。

業務邏輯獨立封裝。每一個單獨的業務都是一個服務對象,友善管理。為 soa 提供了架構基礎。

同時,使用領域服務還可以友善地直接使用 c/s 架構來部署。

舊表中的外鍵引用關系,除了 bill(銷售單) 與 sell(銷售明細) 兩個表間的關系,在設計 uml 時,都設計為實體間的引用關系。先區厘清楚引用關系的可空性,然後就可以在相應實體中編寫引用實體屬性了。例如,stock(庫存)到 good(商品)的關系,被轉換為下面這個引用實體屬性:

bill 和 sell 分别表示銷售訂單、銷售明細項。設計為組合實體後,在使用時,可以直接以組合實體的方式構造、儲存、更新、删除,非常友善。

例如,在添加銷售資訊界面中的代碼如下:

先構造了組合對象,然後送出給領域服務 addbillservice以執行添加銷售資訊邏輯。此服務代碼如下:

待每一個實體修改并替換完畢後,再删除原來的傳統三層項目後,解決方案中就隻剩下了兩個項目,一個 rafy 領域實體項目“cs”;一個原程式中的界面層項目 “clothessys”。

Rafy 領域實體架構示例(1) - 轉換傳統三層應用程式

截止到現在,已經完成了 clothessys 的完整轉換。轉換後的系統已經可以正常的運作,實作了與原系統一緻的功能。

下載下傳該示例代碼後,隻需要修改 app.config 檔案中的連接配接字元串中的使用者名和密碼後,就可以直接運作示例,程式即會自動建立資料庫并成功運作!

下一篇,将展示轉換為使用 rafy 實體架構後,帶來的新功能。