我們在SqlSugar開發框架中,用到的一些設計模式

来源:https://www.cnblogs.com/wuhuacong/p/18025300
-Advertisement-
Play Games

我們在《SqlSugar開發框架》中,有時候都會根據一些需要引入一些設計模式,主要的目的是為瞭解決問題提供便利和代碼重用等目的。而不是為用而用,我們的目的是解決問題,併在一定的場景下以水到渠成的方式處理。不過引入任何的設計模式,都會增加一定的學習難度,除非是自己本身領會比較好了,就會顯得輕鬆一些。本... ...


我們在《SqlSugar開發框架》中,有時候都會根據一些需要引入一些設計模式,主要的目的是為瞭解決問題提供便利和代碼重用等目的。而不是為用而用,我們的目的是解決問題,併在一定的場景下以水到渠成的方式處理。不過引入任何的設計模式,都會增加一定的學習難度,除非是自己本身領會比較好了,就會顯得輕鬆一些。本篇隨筆抽取一些應用場景來介紹相關設計模式,有些地方如列舉有一定的偏頗之處,還請告知以便斧正。

1、Winform的本地訪問和基於Web API的訪問方式

Winform中的界面展示,以及數據處理,都需要具體實現的支撐,由於本身IOC控制反轉的介面設計,我們對具體數據的訪問,也是基於特定的介面層進行調用的,具體的實現,則是在程式啟動的時候,註入對應的介面實現即可。

以上的業務介面層和數據處理層分開,數據處理層會根據配置信息採用不同的資料庫實現方式,如可能是基於SQLServer、Oracle、Mysql、SQLite、PostgreSQL等不同的資料庫,這種方式是軟體開發中常見的一種原則——介面與實現分離的原則,也稱為介面隔離原則(Interface Segregation Principle,ISP)。

介面隔離原則是面向對象設計中的一項原則,它主張一個類不應該強迫其用戶依賴於它們不需要的方法。簡單來說,就是應該將一個介面拆分為多個較小的介面,這樣客戶端只需要知道與其相關的介面即可,而不需要瞭解其他介面的細節。

介面與實現分離的設計模式有很多,常見的包括:

  1. 工廠模式(Factory Pattern):工廠模式通過定義一個創建對象的介面,但是讓子類決定實例化哪個類。這樣,一個類的實例化延遲到其子類。

  2. 抽象工廠模式(Abstract Factory Pattern):抽象工廠模式提供一個創建一系列相關或相互依賴對象的介面,而無需指定它們具體的類。

  3. 適配器模式(Adapter Pattern):適配器模式允許將一個類的介面轉換成客戶希望的另外一個介面,使得原本由於介面不相容而不能一起工作的類可以一起工作。

  4. 代理模式(Proxy Pattern):代理模式為其他對象提供一種代理以控制對這個對象的訪問。代理對象在客戶端和目標對象之間起到中介作用。

在我們有些情況下,不是直接訪問具體的本地資料庫,有可能是間接調用Web API的介面服務的,而我們使用的時候,為了方便,可能需要進行一定的封裝處理,如下圖示。

如果我們這裡增加一個對Web API的調用,那麼在這裡註冊的時候,切換向Web API代理的註冊介面就可以,如下圖所示。

因此原來的Winform界面上的調用代碼,不需要任何變化,只需要註入不同的介面實現,就能獲得不同的方式:普通訪問資料庫方式,還是分散式獲取服務WebAPI的處理方式。

通過切換開關變數的方式,客戶可以非常方便的自由切換不同的數據訪問方式。數據提供服務,可以是直接訪問資料庫的方式,也可以是遠端的Web API服務方式,從而實現更加廣泛的業務需求。

 

2、基於介面和基類的繼承方式簡化重覆代碼

基於介面和基類的繼承方式不是特定的設計模式,而是一種面向對象設計的基本原則和實踐。

這種方式通常用於實現多態性(Polymorphism)、抽象化(Abstraction)和代碼重用。在面向對象的編程語言中,通過定義介面(Interface)和基類(Base Class),可以實現一種規範化的編程模式,讓代碼更加靈活、可擴展和易於維護。

這種方式的優點包括:

  1. 多態性: 通過介面和基類,不同的子類可以實現相同的介面或繼承相同的基類,從而可以以統一的方式對待不同的對象。

  2. 代碼重用: 可以將通用的功能和行為定義在介面或基類中,從而使得子類可以重用這些功能和行為,減少重覆代碼的編寫。

  3. 解耦和模塊化: 介面和基類可以幫助解耦不同模塊之間的依賴關係,提高代碼的模塊化程度,使得系統更易於理解和維護。

雖然基於介面和基類的繼承方式不是一個獨立的設計模式,但它是很多設計模式的基礎,比如工廠模式、策略模式、模板方法模式等都會使用到介面和基類的繼承方式。

在隨筆《基於SqlSugar的開發框架循序漸進介紹(5)-- 在服務層使用介面註入方式實現IOC控制反轉 》我們介紹過具體實現類的繼承關係,一般都是構建相應的基類和介面,然後才是具體的業務實現和介面,這樣處理可以重用基類的很多介面,提高代碼的重用效率。

而對應Web API的代理調用類,那麼為了極大的重用常規的介面處理,我們需要類似的繼承關係。

而在Web API的服務端中,我們為了重用,也是以基類和介面的方式來統一處理相關的邏輯。如我們根據項目的需要,定義了一些Web API控制器的基類,用於實現不同的功能。

同樣,BS的前端和移動端,我們根據框架後端的介面進行前端JS端的類的封裝處理,引入了ES6類的概念實現業務基類介面的統一封裝,簡化代碼。

許可權模塊我們涉及到的用戶管理、機構管理、角色管理、菜單管理、功能管理、操作日誌、登錄日誌等業務類,那麼這些類繼承BaseApi,就會具有相關的介面了,如下所示繼承關係。

按照這個思路,我們在BaseApi的ES6類裡面定義了對應Web API基類裡面的操作方法,如下所示。

 這樣,我們在創建一個業務類的時候,如果沒有特殊的自定義介面,只需要繼承基類BaseApi即可具有所有的常規基類方法了。

 

3、簡單工廠設計模式

簡單工廠模式(Simple Factory Pattern)是一種創建型設計模式,它提供了一個統一的介面來實例化一組相關或相似的對象,而無需暴露對象的創建邏輯給客戶端。

簡單工廠模式包含以下幾個角色:

  1. 工廠(Factory): 負責創建具體產品的類。它通常包含一個或多個靜態方法,根據客戶端的參數來決定創建並返回哪種具體產品的實例。

  2. 產品介面(Product Interface): 聲明瞭具體產品類的共同介面,客戶端通過這個介面與具體產品類進行交互。

  3. 具體產品(Concrete Products): 實現了產品介面的具體類,是工廠創建的目標對象。

簡單工廠模式的核心思想是將對象的創建和使用進行分離,客戶端只需要知道使用工廠提供的介面來獲取所需的產品,而無需瞭解產品是如何被創建的。這樣的設計使得系統更加靈活,可以隨時更改具體產品的創建方式而不影響客戶端的代碼。

在基於《SqlSugar開發框架》中,我們設計了一些系統服務層的基類,在基類中會有很多涉及到相關的數據處理操作的,如果需要跟蹤具體是那個用戶進行操作的,那麼就需要獲得當前用戶的身份信息,包括在Web API的控制器中也是一樣,需要獲得對應的用戶身份信息,才能進行相關的身份鑒別和處理操作。

為了方便獲取用戶身份的信息,我們定義一個介面 IApiUserSession 如下所示。

/// <summary>
/// API介面授權獲取的用戶身份信息-介面
/// </summary>
public interface IApiUserSession
{
    /// <summary>
    /// 用戶登錄來源渠道,0為網站,1為微信,2為安卓APP,3為蘋果APP   
    /// </summary>
    string Channel { get; }

    /// <summary>
    /// 用戶ID
    /// </summary>
    int? Id { get; }

    /// <summary>
    /// 用戶名稱
    /// </summary>
    string Name { get; }

    /// <summary>
    /// 用戶郵箱(可選)   
    /// </summary>
    string Email { get; }

    /// <summary>
    /// 用戶手機(可選)   
    /// </summary>
    string Mobile { get; }

    /// <summary>
    /// 用戶全名稱(可選)   
    /// </summary>
    string FullName { get; }

    /// <summary>
    /// 性別(可選)
    /// </summary>
    string Gender { get; }

    /// <summary>
    /// 所屬公司ID(可選)   
    /// </summary>
    string Company_ID { get; }

    /// <summary>
    /// 所屬公司名稱(可選)   
    /// </summary>
    string CompanyName { get; }

    /// <summary>
    /// 所屬部門ID(可選)   
    /// </summary>
    string Dept_ID { get; }

    /// <summary>
    /// 所屬部門名稱(可選)   
    /// </summary>
    string DeptName { get; }

    /// <summary>
    /// 把用戶信息設置到緩存中去
    /// </summary>
    /// <param name="info">用戶登陸信息</param>
    /// <param name="channel">預設為空,用戶登錄來源渠道:0為網站,1為微信,2為安卓APP,3為蘋果APP </param>
    void SetInfo(LoginUserInfo info, string channel = null);
}

IApiUserSession的一個空白介面定義,它需要依賴於具體的介面實現,我們具體會使用基於Principal或者緩存方式實現記錄用戶身份的信息實現,如下是它們的類關係。

在客戶端和Web API的交換信息過程中,通過JWT的令牌方式,可以攜帶一些相關的用戶身份信息。

在登錄授權的這個時候,控制器會把相關的Claim信息寫入到token中的,我們在客戶端發起對控制器方法的調用的時候,這些身份信息會轉換成對象信息。

在監視視窗中查看IApiUserSession對象,可以查看到對應的信息。

簡單工廠的設計模式,是比較經常用到的一種設計模式,如我在隨筆《基於SqlSugar的開發框架循序漸進介紹(26)-- 實現本地上傳、FTP上傳、阿裡雲OSS上傳三者合一處理》中介紹到,根據配置信息來確定上傳的處理路徑選擇,就是一種簡單的工廠設計模式。

文件上傳處理應該由程式進行配置,決定使用那種方式,那麼這裡面我們為了彈性化處理, 在文件上傳模塊中採用選項模式【Options】處理常規上傳和FTP文件上傳的配置參數信息。

微軟引入選項模式,它是用於配置框架服務使用的設置. 選項模式由Microsoft.Extensions.OptionsNuGet包實現,除了ASP.NET Core應用,它還適用於任何類型的應用程式,如果需要瞭解,微軟的文檔詳細解釋了選項模式。

選項模式的限制之一是你只能解析(註入) IOptions <MyOptions> 併在依賴註入配置完成(即所有模塊的ConfigureServices方法完成)後獲取選項值。如果你正在開發一個模塊,可能需要讓開發者能夠設置一些選項,併在依賴註入註冊階段使用這些選項. 你可能需要根據選項值配置其他服務或更改依賴註入的註冊代碼。IOptions<>是單例,因此一旦生成了,除非通過代碼的方式更改,它的值是不會更新的。

 

在本地文件處理過程中,如果是Web API方式調用服務層,那麼就在Web API所在的文件系統中,如果是Winform界面直接調用服務層,那麼就是在當前系統中處理文件,這種方式可以有效的管理我們的文件信息。

在FTP文件處理過程中,則是根據選項參數的信息,調用FluentFTP類庫進行文件的上傳操作。

在OSS對象存儲處理過程中,我們一般基於阿裡雲、騰訊雲等這些雲服務OSS的處理方式,一般它們會提供相應開發語言的SDK,我們引用併進行整合即可。

對於阿裡雲的OSS來說,對應的AccesKey和SecretKey自己可以通過查看賬戶的信息可以獲取到。

 

以上就是一些場景的應用設計模式,當前開發框架裡面,有很多其他的場景也同樣會引入一些不同的處理方法,不過主旨都是希望採用較小的代價和難度,來解決複雜的問題的思路。

 

鏈接附註

如對我們的代碼生成工具有興趣,可以到官網下載使用《代碼生成工具Database2Sharp》。

如需瞭解我們官網對《SqlSugar開發框架》的介紹,可以參考《SqlSugar開發框架》瞭解。

如需閱讀我們對於《SqlSugar開發框架》文章介紹,可以參考博客園的隨筆標簽《SqlSugar隨筆 , WPF隨筆》學習瞭解。

 

專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
  轉載請註明出處:撰寫人:伍華聰  http://www.iqidi.com 
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大家好,我是知微! 上一篇推薦的書單嵌入式軟體必讀10本書_單片機篇,收到反響很好。再推薦一篇嵌入式Linux相關的書單。 《鳥哥的Linux私房菜》 鳥哥的Linux系列適合零基礎小伙伴,從電腦基礎到文件系統、shell腳本等等,通俗易懂。作者寫作風格生動幽默,不拘一格。雖然書有點厚,但對於新手而 ...
  • Linux下MySQL的安裝與使用 安裝前說明 查看是否安裝過MySQL 如果你是用rpm安裝, 檢查一下RPM PACKAGE: rpm -qa | grep -i mysql # -i 忽略大小寫 檢查mysql service: systemctl status mysqld.service ...
  • 資料庫作為數據驅動業務創新和智慧銀行建設的關鍵基礎設施,在銀行數字化變革中具有舉足輕重的作用。 在金融科技發展和國家政策引領下,銀行紛紛加快推進數字化轉型時代,正在經歷一場以科技引領、數據賦能、數字經營為目標的智慧銀行數字化變革。資料庫作為數據驅動業務創新和智慧銀行建設的關鍵基礎設施,在銀行數字化變 ...
  • 本文分享自華為雲社區《面試必問 | 聊聊MySQL三大核心日誌的實現原理?》,作者:冰 河。 MySQL幾乎成為互聯網行業使用的最多的開源關係型資料庫,正因如此,MySQL也成為各大互聯網公司面試中必問的資料庫,尤其是MySQL中的事務實現機制和三大核心日誌的實現原理。 今天,我們就重點聊聊MySQ ...
  • 近期,Apache DolphinScheduler 社區激動地宣佈 3.2.1 版本的發佈。此次更新不僅著力解決了前一版本(3.2.0)中遺留的問題,而且引入了一系列的功能增強和優化措施。 原先的問題主要源於部分重要代碼在發佈過程中未能成功合併(cherry-pick),加之這部分代碼的合併過程較 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 一、什麼是SPA SPA(single-page application),翻譯過來就是單頁應用SPA是一種網路應用程式或網站的模型,它通過動態重寫當前頁面來與用戶交互,這種方法避免了頁面之間切換打斷用戶體驗在單頁應用中,所有必要的代碼( ...
  • 訂單履約系統用來管理從接到銷售訂單,到把貨品送到客戶手中的整個業務過程。它是上游交易(如銷售和客戶下單環節)和下游倉儲配送(如庫存管理、物流)之間的橋梁,確保信息流的順暢和操作的協同,提升整個供應鏈的效率和響應速度。 ...
  • 概括 這是一道PHP反序列化的CTF賽題,本意是想用這道題對PHP反序列化進行一定的學習。 過程 我們打開賽題,看看內容 沒有發現什麼東西,看看他的頁面代碼 根據他的提示,感覺是存在一個robots.txt文件的,嘗試訪問一下。 進去看看。 果然如此 我們來分析一下這段代碼 <?php error_ ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...