我們在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
  • 下麵是一個標準的IDistributedCache用例: public class SomeService(IDistributedCache cache) { public async Task<SomeInformation> GetSomeInformationAsync (string na ...
  • 這個庫提供了在啟動期間實例化已註冊的單例,而不是在首次使用它時實例化。 單例通常在首次使用時創建,這可能會導致響應傳入請求的延遲高於平時。在註冊時創建實例有助於防止第一次Request請求的SLA 以往我們要在註冊的時候實例單例可能會這樣寫: //註冊: services.AddSingleton< ...
  • 最近公司的很多項目都要改單點登錄了,不過大部分都還沒敲定,目前立刻要做的就只有一個比較老的項目 先改一個試試手,主要目標就是最短最快實現功能 首先因為要保留原登錄方式,所以頁面上的改動就是在原來登錄頁面下加一個SSO登錄入口 用超鏈接寫的入口,頁面改造後如下圖: 其中超鏈接的 href="Staff ...
  • Like運算符很好用,特別是它所提供的其中*、?這兩種通配符,在Windows文件系統和各類項目中運用非常廣泛。 但Like運算符僅在VB中支持,在C#中,如何實現呢? 以下是關於LikeString的四種實現方式,其中第四種為Regex正則表達式實現,且在.NET Standard 2.0及以上平... ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他們的程式記憶體會偶發性暴漲,自己分析了下是非托管記憶體問題,讓我幫忙看下怎麼回事?哈哈,看到這個dump我還是非常有興趣的,居然還有這種游戲幣自助機類型的程式,下次去大玩家看看他們出幣的機器後端是不是C#寫的?由於dump是linux上的程式,剛好win ...
  • 前言 大家好,我是老馬。很高興遇到你。 我們為 java 開發者實現了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何處理的,可以參考我的另一個項目: 手寫從零實現簡易版 tomcat minicat 手寫 ngin ...
  • 上一次的介紹,主要圍繞如何統一去捕獲異常,以及為每一種異常添加自己的Mapper實現,並且我們知道,當在ExceptionMapper中返回非200的Response,不支持application/json的響應類型,而是寫死的text/plain類型。 Filter為二方包異常手動捕獲 參考:ht ...
  • 大家好,我是R哥。 今天分享一個爽飛了的面試輔導 case: 這個杭州兄弟空窗期 1 個月+,面試了 6 家公司 0 Offer,不知道問題出在哪,難道是杭州的 IT 崩盤了麽? 報名面試輔導後,經過一個多月的輔導打磨,現在成功入職某上市公司,漲薪 30%+,955 工作制,不咋加班,還不捲。 其他 ...
  • 引入依賴 <!--Freemarker wls--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency> ...
  • 你應如何運行程式 互動式命令模式 開始一個互動式會話 一般是在操作系統命令行下輸入python,且不帶任何參數 系統路徑 如果沒有設置系統的PATH環境變數來包括Python的安裝路徑,可能需要機器上Python可執行文件的完整路徑來代替python 運行的位置:代碼位置 不要輸入的內容:提示符和註 ...