分類
發燒車訊

如何使用ABP進行軟件開發之基礎概覽

ABP框架簡述

1)簡介

在.NET眾多的技術框架中,ABP框架(本系列中指aspnetboilerplate項目)以其獨特的魅力吸引了一群優秀開發者廣泛的使用。

在該框架的賦能之下,開發者可根據需求通過官方網站【https://aspnetboilerplate.com/Templates】選擇下載例如Vue/AngluarJS/MVC等不同類型的模板項目,輕鬆加入ABP開發者的隊伍中,盡享基於ABP開發帶來的樂趣。

ABP開發框架也提供了豐富的文檔,能夠為開發者帶來許多便捷。目前ABP的文檔網站為:

官方文檔:https://aspnetboilerplate.com/Pages/Documents

文檔庫不可謂不全,加上國內眾多的ABP開發者參与的活躍的技術圈子,使得學習成本只是在第一個項目中比較高,後期將會越來越平滑。

2)現狀

當然,目前ABP的框架開發者和社區已經把更多的精力投入到了ABP.VNEXT開發框架,這個新框架以其DDD+微服務+模塊化的理念獲得了大量擁躉,使ABP框架的開發優先級已經開始逐漸降低。

但這是因為ABP框架的功能已經成熟穩定,且ABP是一種增量式的架構設計,開發者在熟練掌握這種框架后,可以根據自己的需要進行方便的擴展,使其成為小項目架構選型中一種不錯的備選方案。

當然,也存在一些弊端。例如由於ABP被稱為.NET眾多開發框架中面向領域驅動設計的最佳實踐,而囿於領域驅動設計本身不低的門檻,使得學習的過程變得看起來非常陡峭;

除此之外,ABP也廣泛使用了目前Asp.NET/Asp.NET Core框架的大量比較新的特性,對於不少無法由於各種原因無法享受.NET技術飛速發展紅利的傳統開發者來說,無形中也提高了技術門檻。

3)綜述

在這個系列中,本文計劃分成三篇來介紹ABP框架,第一篇介紹ABP的基礎概覽,介紹基礎知識,第二篇介紹ABP的模式實踐,第三篇,試圖介紹如何從更傳統的三層甚至是單層+SQL的單層架構,如何遷移到ABP框架。

(畢竟。。.NET遺留應用實在是太多了,拯救或不拯救?)

代碼結構結構

基本文件夾簡述

當我們通過ABP模板項目的官方網站下載一個項目后,我們所獲得的代碼包的結構如下圖所示,其中:

  • vue為使用iview框架構建的管理系統基本模板,該腳手架使用了yarn作為包管理器,並集成了vuex/axios等常用框架,並提供了用戶,租戶,權限三個基本功能的示例代碼,開發者只需發揮聰明才智就能快速的通過該框架入手前端項目。
  • (當然,該項目廣泛使用了typescript+面向對象的設計,似乎前端開發者。。普遍不擅長面向對象開發?)
  • aspnet-core則是一個完整的asp.netcore項目的快速開發腳手架。該腳手架集成了docker打包於一體,並包含基本的單元測試示例,使用了identity作為權限控制單元,使用swagger作為接口文檔管理工具,集成了efcore、jwt等常用組件,對於開發者來說,基本上算是開箱即用了。

前端vue項目

打開vue文件夾之後,該項目的基本目錄如下圖所示。(src文件夾)

lib文件夾

定義了與abp+vue腳手架項目的基礎組件和常見類庫,封裝了一系列基本方法。例如權限控制,數據請求,菜單操作,SignalR等基礎組件的用法。

router文件夾

定義了vue項目的路由規則,其中index.ts文件是項目的入口,router.ts文件定義了vue文件的路由規則。

store文件夾

由於本項目使用了vuex框架,所以我們可以來看看對於store文件夾的介紹。

在vuex框架中:

每一個 Vuex 應用的核心就是 store(倉庫)。“store”基本上就是一個容器,它包含着你的應用中大部分的狀態 (state)。
Vuex 和單純的全局對象有以下兩點不同:
Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。
你不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地了解我們的應用。

即vuex框架中,將原來的請求鏈路,抽象化為狀態的變化,通過維護狀態,使得數據的管理更加便捷,也易於擴展。

views文件夾

定義了登錄、首頁、用戶、角色、租戶的基本頁面,並提供了新增、查看、編輯、刪除的代碼示例。

綜上,該項目是一個結構清晰,邏輯縝密的前端框架,可以作為常見管理系統的腳手架。

後端項目

簡介

後端項目是一個遵循了領域驅動設計的分層,同時又符合Robert Martin在《代碼整潔之道》提出的【整潔架構】。

領域驅動設計簡介

在領域驅動設計的分層設計中,共有四個功能分層,分別是:

表示層(Presentation Layer):為用戶提供接口,使用應用層實現用戶交互。

應用層(Application Layer):介於用戶層和領域層之間,協調用戶對象,完成對應的任務。

領域層(Domain Layer):包含業務對象和規則,是應用程序的心臟。

基礎設施層(Infrastructure Layer):提供高層級的通用技術功能,主要使用第三方庫完成。

在後文中,基於abp對領域驅動設計的功能分層將進行多次、詳細敘述,本小節不再贅述。

整潔架構簡介

整潔架構是由Bob大叔提出的一種架構模型,來源於《整潔架構》這本書,顧名思義,其目的並不是為了介紹這一種優秀的架構本身,而是介紹如何設計一種整潔的架構,使得代碼結構易於維護。

(整潔架構就是這樣一個洋蔥,所以也有人稱它為“洋蔥”架構)

  1. 依賴規則(Dependency Rule)

用一組同心圓來表示軟件的不同領域。一般來說,越深入代表你的軟件層次越高。外圓是戰術是實現機制(mechanisms),內圓的是核心原則(policy)。

Policy means the application logic.

Mechanism means the domain primitives.

使此體系架構能夠工作的關鍵是依賴規則。這條規則規定軟件模塊只能向內依賴,而裏面的部分對外面的模塊一無所知,也就是內部不依賴外部,而外部依賴內部。同樣,在外面圈中使用的數據格式不應被內圈中使用,特別是如果這些數據格式是由外面一圈的框架生成的。我們不希望任何外圓的東西會影響內圈層

  1. 實體 (Entities)

實體封裝的是整個企業範圍內的業務核心原則(policy),一個實體能是一個帶有方法的對象,或者是一系列數據結構和函數,只要這個實體能夠被不同的應用程序使用即可。

如果你沒有編寫企業軟件,只是編寫簡單的應用程序,這些實體就是應用的業務對象,它們封裝着最普通的高級別業務規則,你不能希望這些實體對象被一個頁面的分頁導航功能改變,也不能被安全機制改變,操作實現層面的任何改變不能影響實體層,只有業務需求改變了才可以改變實體

  1. 用例 (Use case)

在這個層的軟件包含只和應用相關的業務規則,它封裝和實現系統的所有用例,這些用例會混合各種來自實體的各種數據流程,並且指導這些實體使用企業規則來完成用例的功能目標。

我們並不期望改變這層會影響實體層. 我們也不期望這層被更外部如數據庫 UI或普通框架影響,而這也正是我們分離出這一層來的原因所在。

然而,應用層面的操作改變將會影響到這個用例層,如果需求中用例發生改變,這個層的代碼就會隨之發生改變。所以可以看到,這一層是和應用本身緊密相關的

  1. 接口適配器 (Interface Adapters)

這一層的軟件基本都是一些適配器,主要用於將用例和實體中的數據轉換為外部系統如數據庫或Web使用的數據,在這個層次,可以包含一些GUI的MVC架構,表現視圖 控制器都屬於這個層,模型Model是從控制器傳遞到用例或從用例傳遞到視圖的數據結構。

通常在這個層數據被轉換,從用例和實體使用的數據格式轉換到持久層框架使用的數據,主要是為了存儲到數據庫中,這個圈層的代碼是一點和數據庫沒有任何關係,如果數據庫是一個SQL數據庫, 這個層限制使用SQL語句以及任何和數據庫打交道的事情。

  1. 框架和驅動器

最外面一圈通常是由一些框架和工具組成,如數據庫Database, Web框架等. 通常你不必在這個層不必寫太多代碼,而是寫些膠水性質的代碼與內層進行粘結通訊。

這個層是細節所在,Web技術是細節,數據庫是細節,我們將這些實現細節放在外面以免它們對我們的業務規則造成影響傷害

ABP的分層實現

在ABP項目中,層次劃分如下。

1. 應用層(Application項目)

在領域驅動設計的分層式架構中,應用層作為應用系統的北向網關,對外提供業務外觀的功能。在Abp模板項目中,Application項目也是編寫主要用例代碼的位置,開發者們在此定義與界面有關的數據行為,實現面向接口的開發實踐。

應用服務層包含應用服務,數據傳輸單元,工作單元等對象。

  • Application Service

為面向用戶界面層實現業務邏輯代碼。例如需要為某些界面對象組裝模型,通常會定義ApplicationService,並通過DTO對象,實現與界面表現層的數據交換。

  • Data Transfer Object (DTO)

最常見的數據結構為DTO(數據傳輸對象),這是來源於馬丁弗勒在《企業架構應用模式》中提到的名詞,其主要作用為:

是一種設計模式之間傳輸數據的軟件應用系統。 數據傳輸目標往往是數據訪問對象從數據庫中檢索數據。

在ABP的設計中,有兩種不同類型的DTO,分別是用於新增、修改、刪除的Input DTO,和用於查詢的Output DTO。

  • Unit of Work:

工作單元。工作單元與事務類似,封裝了一系列原子級的數據庫操作。

2. 核心層(Core項目)

核心層包含領域實體、值對象、聚合根,以及領域上下文實現。

  • Entity(實體):

實體有別於傳統意義上大家所理解的與數據庫字段一一匹配的實體模型,在領域驅動設計中,雖然實體同樣可能持久化到數據庫,但實體包含屬性和行為兩種不同的抽象。

例如,如果有一個實體為User,其中有一個屬性為Phone,數據為086-132xxxxxxxx,我們有時需要判斷該手機號碼的國際代號,可能會添加一個新的判定 GetNationCode(),可以通過從Phone字段中取出086來實現,這就是一種通俗意義上的行為。

  • Value Object(值對象):

值對象無需持久化到數據庫,往往是從其他實體或聚合中“剝離”出來的與某些聚合具備邏輯相關性或語義相關性的對象,有時值對象甚至只有個別屬性。

例如,上述實體,包含Phone字段,我們可以將整個Phone“剝離”為一個Telephone對象,該對象可包含PhoneNumber和NationCode字段。

public class User
{
     public Telephone Phone{public get;private set;}
}
public class Telephone
{
    public string  PhoneNumber {get;set;}
     public string NationCode  {get;set;}
}
  • Aggregate & Aggregate Root(聚合,聚合根):

聚合是業務的最小工作單元,有時,一個實體就是一個小聚合,而為聚合對外提供訪問機制的對象,就是聚合根。

在領域驅動設計中,識別聚合也是一件非常重要的工作,有一組系統的方法論可以為我們提供參考。

當然,事實上識別領域對象,包括且不限定於識別聚合、值對象、實體識別該對象的行為或(方法)本身是一件需要經驗完成的工作,有時需要UML建模方法的廣泛參与。

有時,我們會習慣於通過屬性賦值完成梭代碼的過程,從而造成領域行為流失在業務邏輯層的問題,那麼或許可以採取這樣的方法:

1、對象的創建,使用構造函數賦值,或工廠方法創建。

2、將所有對於屬性的訪問級別都設置為

public string Phone{public get;private set;}

然後再通過一個綁定手機號碼的方法,來給這個對象設置手機號碼。

public string BindPhone(string phone)
{
}

將所有一切涉及到對Phone的操作,都只能通過規定的方法來賦值,這樣可以實現我們開發過程中,無意識的通過屬性賦值,可能導致的“領域行為”丟失的現象發生。
這種方式可以使得對對象某些屬性的操作,只能通過唯一的入口完成,符合單一職責原則的合理運用,如果要擴展方法,可以使用開閉原則來解決。

但是,採用這種方式,得盡量避免出現:SetPhone(string phone) 這樣的方法出現,畢竟這樣的方法,其實和直接的屬性賦值,沒有任何區別。

  • Repository(倉儲)

倉儲封裝了一系列對象數據庫操作的方法,完成對象從數據庫到對象的轉換過程。在領域驅動設計中,一個倉儲往往會負責一個聚合對象從數據庫到創建的全過程。

  • Domain Service(領域服務)

領域服務就是“實幹家”,那些不適合在領域對象中出現,又不屬於對象數據庫操作的方法,又與領域對象息息相關的方法,都可以放到領域服務中實現。

  • Specification(規格定義)

規範模式是一種特殊的軟件設計模式,通過使用布爾邏輯將業務規則鏈接在一起,可以重新組合業務規則。

實際上,它主要用於為實體或其他業務對象定義可重用的過濾器。

3. 其他基礎設施(EntityFrameworkCore,Web.Core,Web.Host項目)

EntityFrameworkCore負責定義數據庫上下文和對EFCore操作的一系列規則、例如種子數據的初始化等。

Web.Core:定義了應用程序的外觀和接口。雖然從表面上看,Web.Core定義了作為Web訪問入口的控制器方法和登錄驗證的邏輯,看起來像是用戶表現層的東西,但是仔細想想,這些東西,何嘗不是一種基礎設施?

Web.Host:定義WEB應用程序的入口。

總結

本文簡述了ABP框架的前後端項目的分層結構,通過了解這些結構,將有助於我們在後續的實戰中更快入手,為應用開發插上翅膀。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務