我們在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
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...