我们在SqlSugar开发框架中,用到的一些设计模式

2024-02-22 19:28

本文主要是介绍我们在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自己可以通过查看账户的信息可以获取到。

以上就是一些场景的应用设计模式,当前开发框架里面,有很多其他的场景也同样会引入一些不同的处理方法,不过主旨都是希望采用较小的代价和难度,来解决复杂的问题的思路。

文章转载自:伍华聪

原文链接:https://www.cnblogs.com/wuhuacong/p/18025300

体验地址:引迈 - JNPF快速开发平台_低代码开发平台_零代码开发平台_流程设计器_表单引擎_工作流引擎_软件架构

这篇关于我们在SqlSugar开发框架中,用到的一些设计模式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/736249

相关文章

基于Python开发电脑定时关机工具

《基于Python开发电脑定时关机工具》这篇文章主要为大家详细介绍了如何基于Python开发一个电脑定时关机工具,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 简介2. 运行效果3. 相关源码1. 简介这个程序就像一个“忠实的管家”,帮你按时关掉电脑,而且全程不需要你多做

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

基于Qt开发一个简单的OFD阅读器

《基于Qt开发一个简单的OFD阅读器》这篇文章主要为大家详细介绍了如何使用Qt框架开发一个功能强大且性能优异的OFD阅读器,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 目录摘要引言一、OFD文件格式解析二、文档结构解析三、页面渲染四、用户交互五、性能优化六、示例代码七、未来发展方向八、结论摘要

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

MyBatis框架实现一个简单的数据查询操作

《MyBatis框架实现一个简单的数据查询操作》本文介绍了MyBatis框架下进行数据查询操作的详细步骤,括创建实体类、编写SQL标签、配置Mapper、开启驼峰命名映射以及执行SQL语句等,感兴趣的... 基于在前面几章我们已经学习了对MyBATis进行环境配置,并利用SqlSessionFactory核

C#图表开发之Chart详解

《C#图表开发之Chart详解》C#中的Chart控件用于开发图表功能,具有Series和ChartArea两个重要属性,Series属性是SeriesCollection类型,包含多个Series对... 目录OverviChina编程ewSeries类总结OverviewC#中,开发图表功能的控件是Char

鸿蒙开发搭建flutter适配的开发环境

《鸿蒙开发搭建flutter适配的开发环境》文章详细介绍了在Windows系统上如何创建和运行鸿蒙Flutter项目,包括使用flutterdoctor检测环境、创建项目、编译HAP包以及在真机上运... 目录环境搭建创建运行项目打包项目总结环境搭建1.安装 DevEco Studio NEXT IDE

Python开发围棋游戏的实例代码(实现全部功能)

《Python开发围棋游戏的实例代码(实现全部功能)》围棋是一种古老而复杂的策略棋类游戏,起源于中国,已有超过2500年的历史,本文介绍了如何用Python开发一个简单的围棋游戏,实例代码涵盖了游戏的... 目录1. 围棋游戏概述1.1 游戏规则1.2 游戏设计思路2. 环境准备3. 创建棋盘3.1 棋盘类

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD