.Net普通三层->工厂模式->线程内唯一+单元工作模式->WebService分布式三层

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/38023225 在...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq1010885678/article/details/38023225

在软件世界分层的思想无处不在

主要是为了提高软件系统的维护性,扩展性,复用性和解耦等

软件的三层构架是一种最基本的分层思想的体现

结构图大体如下:


如此一来,开发人员可以只关注其中一层,而无需关心下一层是如何实现的

但是最基本的三层构架在软件系统中很明显是不够用的

因为它带来优点的同时也带着许多缺点,比如耦合性高,经常出现修改某一层的代码另外一层也要随之大幅度整顿

而且当需求发生改变的时候,如:原先开发的时候使用mssql数据库,而现在又要求更换成mysql数据库

更换Dal层会导致Bll层也要重新设计

这时便可以使用工厂模式的三层

基本构架如下:


其实就是Bll和Dal层的代码分别实现他们接口层的接口

这体现了软件设计的针对接口编程的原则

为什么需要多出接口层实现呢

如,只要实现了IDAL层的接口

无论是mssql的Dal还是mysql的Dal层都可以随意的替换

通过一个工厂类来提供IDAL接口层的实体对象

Bll层中就只需要调用IDAL接口层中的方法就可以了而无需关心是谁实现的,怎么实现的

这时候如果要更换数据库所要修改的代码就大幅度减少了

只需要修改工厂类中相关的代码就可以,Bll层基本无需改动

但是这还是会修改代码

违反了软件设计原则中对扩展开发,对修改封闭的原则(开放-封闭原则)

我们可以利用反射技术来解决这个问题

我们可以再配置文件中配置好IDAL层中接口和Dal层中数据操作类所在的程序集名和所在的命名空间

在工厂类中根据配置文件中的信息利用反射动态创建Dal层的实体对象并转成IDAL中的接口

然后提供给Bll层使用

现在如果要更换数据库只需要更改配置文件中对应的程序集和命名空间信息就搞定,代码不需修改一行

(更绝的是,可以将配置信息放入数据库中,然后提供一个配置页面进行切换配置信息操作,这样一来连配置文件都不需要修改!)

上图中


因为各个实体类的CRUD方法都是差不多的,因此抽象出一个IBaseDal接口规定了CRUD的方法,并让IDAL层的所有接口都继承于这个基接口

同样对于Dal层的数据操作类,抽象出一个BaseDal基类,实现了IBaseDal中规定的CRUD基本方法,再次实现了代码复用


但是在很多的应用场景(如Web网站)

由于用户量大,可能导致很多问题,如数据不同步等多线程问题

可以采用线程内唯一的方案来对此问题进行改善

线程内唯一就是保证一个用户请求,访问的过程中只通过一个数据上下文进行操作,这样就不会出现因为缓存等情况而出现的数据混乱



上图在工厂模式的三层构架基础上添加了几个关键点:

1.在数据访问驱动之上设置了一个DbContextFactory工厂类,在此工厂类的内部通过CallContext方法从数据槽中取得唯一的数据访问驱动上下文

2.在IDAL接口层之上增设了DalContext层,该层是为了给Bll层一个调用IDAL接口的统一入口,但是其更重要的一个功能是通过一个公有的SaveChanges方法实现单元工作

3.和数据访问驱动层一样,在IDAL统一入口处设置了一个DalContextFactory工厂类来确保这个入口是线程内唯一的

那么什么是单元工作

比如在一个业务需求中

要对Users表进行添加

对Roles表进行删除

然后对Users和Roles的中间表进行修改

那么在此程序就会与数据库交互三次

但是如果是将三个操作线放入一个缓存中,等到最后一起提交到数据库

这样一来就减少了数据库的交互次数,提高了数据库的吞吐量

这就是单元工作模式

在EF中可以轻易的实现这个功能(在数据操作类中最后一步不要使用数据上下文的SaveChange保存操作,而是将其封装到DalContext中,使得Bll层可以在执行一系列的业务操作之后调用DalContext的SaveChanges方法进行统一的保存修改)

使用ADO.NET的话大致的思路就是将要执行的sql语句放入一个缓存队列中

通过另外一个工作进程通过轮询的方式(每隔一段时间,这个时间段间隔是非常小的)从缓存队列中取出sql语句一起提交到数据库


最后就是分布式的三层架构


我们可以通过WebService来比较简单的实现这一构架
在每层的WebService中通过该层的基本服务(简单三层,工厂三层或者线程内唯一+单元工作的三层等)
得到对应的接口
并通过这些接口的方法来接收和处理上一层发送的请求

相关文章
|
11月前
|
负载均衡 算法 安全
基于Reactor模式的高性能网络库之线程池组件设计篇
EventLoopThreadPool 是 Reactor 模式中实现“一个主线程 + 多个工作线程”的关键组件,用于高效管理多个 EventLoop 并在多核 CPU 上分担高并发 I/O 压力。通过封装 Thread 类和 EventLoopThread,实现线程创建、管理和事件循环的调度,形成线程池结构。每个 EventLoopThread 管理一个子线程与对应的 EventLoop(subloop),主线程(base loop)通过负载均衡算法将任务派发至各 subloop,从而提升系统性能与并发处理能力。
556 3
|
机器学习/深度学习 监控 算法
局域网行为监控软件 C# 多线程数据包捕获算法:基于 KMP 模式匹配的内容分析优化方案探索
本文探讨了一种结合KMP算法的多线程数据包捕获与分析方案,用于局域网行为监控。通过C#实现,该系统可高效检测敏感内容、管理URL访问、分析协议及审计日志。实验表明,相较于传统算法,KMP在处理大规模网络流量时效率显著提升。未来可在算法优化、多模式匹配及机器学习等领域进一步研究。
309 0
|
SQL 数据建模 BI
【YashanDB 知识库】用 yasldr 配置 Bulkload 模式作单线程迁移 300G 的业务数据到分布式数据库,迁移任务频繁出错
问题描述 详细版本:YashanDB Server Enterprise Edition Release 23.2.4.100 x86_64 6db1237 影响范围: 离线数据迁移场景,影响业务数据入库。 外场将部分 NewCIS 的报表业务放到分布式数据库,验证 SQL 性能水平。 操作系统环境配置: 125G 内存 32C CPU 2T 的 HDD 磁盘 问题出现的步骤/操作: 1、部署崖山分布式数据库 1mm 1cn 3dn 单线启动 yasldr 数据迁移任务,设置 32 线程的 bulk load 模式 2、观察 yasldr.log 是否出现如下错
|
存储 NoSQL MongoDB
.NET MongoDB数据仓储和工作单元模式封装
.NET MongoDB数据仓储和工作单元模式封装
295 15
|
开发框架 监控 .NET
C#进阶-ASP.NET WebForms调用ASMX的WebService接口
通过本文的介绍,希望您能深入理解并掌握ASP.NET WebForms中调用ASMX WebService接口的方法和技巧,并在实际项目中灵活运用这些技术,提高开发效率和应用性能。
1132 5
|
开发框架 Java .NET
.net core 非阻塞的异步编程 及 线程调度过程
【11月更文挑战第12天】本文介绍了.NET Core中的非阻塞异步编程,包括其基本概念、实现方式及应用示例。通过`async`和`await`关键字,程序可在等待I/O操作时保持线程不被阻塞,提高性能。文章还详细说明了异步方法的基础示例、线程调度过程、延续任务机制、同步上下文的作用以及如何使用`Task.WhenAll`和`Task.WhenAny`处理多个异步任务的并发执行。
439 1
|
监控
Saga模式在分布式系统中保证事务的隔离性
Saga模式在分布式系统中保证事务的隔离性
382 4
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
605 4
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法