当前位置: 首页 > news >正文

NET架构设计—第四章—业务层分层架构(前篇)

不是所有的应用程序都是一样的,也不是所有的系统都需要用复杂的架构来组织业务逻辑。作为开发人员,我们必须清楚每一种业务逻辑组织的模式,这样我们才能在需要的时候做出合适的选择。

Transaction Script

这种组织业务逻辑的模式是最简单,也是最容易理解的。Transaction Script模式就是用面向过程的方式来组织业务逻辑的。通常情况下,系统的一个流程就被实现为一个方法,然后把所有的这些方法组织在一起,放在一个静态的manager类或者service 类中。实现流程的那个方法包含了业务逻辑的Check和Validation,数据的持久化以及其他的一些相关操作。也就是说,一个方法把所有的事情都做完了。当然,有时候这个大的方法还可能被拆成小的方法,便于重用。

Transaction Script一个好处就是理解起来很简单,尤其是当Team中的一个新成员来说,更是如此,因为他几乎不用花什么时间,就能立刻明白这种组织业务逻辑的方式。每当来了一个新的需求的时候,要做的事情就是去加上一个或者一些新的方法来是实现这个需求,而其还不会影响其他已经存在的功能。

对于一个很小的或者基本山没什么业务逻辑的系统来说,用Transaction Script模式组织业务逻辑还是很不错的,而且对一个刚刚踏入IT的开发人员门槛也比较低。:当系统开始变大,业务逻辑开始变得复杂的时候Transaction Script的问题的出来了。最后的结果可能就是系统中存在大量的方法,而且这些方法中到处都是重复的代码。有的时候,我们可以提炼出一些业务逻辑的验证代码组织为方法,但是我们去很难提炼出一些在流程上相识的代码,即使两个流程只有一点点的不同。如果系统的需求稍微一边,导致流程变了一点点,那么很多的方法就要改动,而且我们还得在系统中去找出那些相似的流程代码,然后修改,万一哪个方法没有找出,后果可想而知。

下面我们就用一个人事请假管理系统为例子来看看Transaction Script是如何实现的。因为Transaction Script很简单,所以下面的代码也只是用于演示,大家理解就行了。

代码

一眼看上去,我们就很容易理解这种面向过程的方式:系统中的所有的用例都被组织成了一个个的方法。例如在BookHolidayFor方法中就做了很多的事情:查询和持久化数据,是否允许请教的业务逻辑的实现等。

如果在一个很简单的,业务很少的系统中采用这种方式还是可以的,随着业务逻辑的越来越复杂,我们就得重新考虑下这种组织逻辑的方式,越早发现,越早做出改变,以后的成本将会越小。

Active Record

下面就以一个内容管理系统中的文章管理功能为例来讲述如何使用活动记录模式来组织业务逻辑。相信大家对内容管理管理系统(CMS)都有一些了解,对于文章模块,用户可以发布文章,游客或其他用户可以发表评论。在相应的数据库中,存在着文章表tb_Articles和评论表tb_Comments,

在Active Record模式中,每一个业务对象各自负责自己的数据持久化逻辑和相关的业务逻辑。正如前面提到的:Active Record模式很适合那种“业务对象和数据表一 一对应”的简单的应用程序,例如Blog,Forum等系统。因为在Active Record模式中,每一个业务类和表都有对应的关系,而且业务类都包含了CRUD的操作,那么我们可以使用一些代码生成工具来加速我们的开发,而且有些好的代码生成工具还包含了一些数据库的逻辑验证代码来确保我们把正确的数据保存到数据库中。

下面我们就用一个例子来看看这种模式是如何应用的。例子还是采用之前谈到的CMS Blog系统。

在业务层,业务类Article和Comment的结构如图所示

在Active Record模式中,每一个业务对象各自负责自己的数据持久化逻辑和相关的业务逻辑

正如前面提到的:Active Record模式很适合“业务对象和数据表一一对应”的应用程序,例如Blog、Forum等系统;同时Active Record模式也比较适合“数据为先”的应用程序:根据现有的数据库来组织逻辑和建立业务模型。

因为在Active Record模式中,每一个业务类和表都有对应的关系,而且业务类都包含了CRUD的操作,我们可以使用一些代码生成工具来加速开发,而且有些好的代码生成工具还包含了一些数据库的逻辑验证代码,以确保我们把正确的数据保存到数据库中。例如,在.NET中,可以直接使用Castle 的Active Record Framework来快速开发应用程序。

下面就使用Castle ActiveRecord框架来开发上面的文章管理模块

[ActiveRecord("tb_Comments")]
public class Comment : ActiveRecordBase<Comment>
{
[PrimaryKey]
public int Id { get; set; }

[BelongsTo("ArticleID")]
public Article Post { get; set; }

[Property]
public string Subject { get; set; }

[Property]
public string Content { get; set; }

[Property]
public DateTime CreatedDate { get; set; }

[Property]
public string CreatedBy { get; set; }

[Property]
public DateTime UpdatedDate { get; set; }
}

上面的代码可以看成类似ORM的映射过程:在Comment类加上Attribute,表明这个属性和数据表中同名的列对应(在Castle.ActiveRecord框架内部也采用了NHibernate,所以,上面实际上就是NHibernate的映射)。

从上面的一些工作量可以看出,用相应的Frameword来实现blog系统还是比较的快的。而且上面的例子中,业务类和表的结构很一致,这也是Active Record的特点和优势。但是如果业务类和数据表的结构不一致,而且逻辑也变复杂了,也就是出现了“抗阻不匹配”。如果还在这中模式上面坚持,会使后面的开始过程和代码维护变得困难,那么我们就得采用Domain Model模式来组织业务逻辑。

http://www.jsqmd.com/news/1125502/

相关文章:

  • 5 天逆向极验4滑块验证码:从 30 万行混淆 JS 到纯协议 5/5 success
  • 数据库查询优化器<1>查询重写 / 逻辑优化
  • QA Use:推荐一款AI 原生 E2E 测试平台,自然语言一键跑通用例!
  • (干货整理)实测靠谱的AI论文写作软件,毕业生收藏备用
  • 115、Gold-YOLO 黄金特征聚合 Neck 的 YOLOv11 实现:Low-FAM 和 High-FAM 双路径融合
  • 少儿C++分级课程体系搭建:从L1到L4的教学设计经验分享
  • 由罗技 K380 键盘 FN 键模式切换引发的血案
  • Meta Assistant / 告别命令行,我为一堆 Python 脚本做了一个 Windows 任务栏的“家”
  • 桌面AI Agent从原理到实践:以“昔涟”为例解析LLM与操作系统协同
  • 设置Shell脚本开机自启
  • 基于 superpowers 实现复杂前端改造
  • STM32G070RB与TB9051FTG实现直流电机静音控制方案
  • 基于51单片机RFID车位车库管理系统/RC522读卡/车库收费系统21(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 结合Nginx工作流程理解Epoll机制和Reactor模型
  • C 语言 typedef 的用法
  • 基于51/STM32单片机分贝仪检测 噪音等级声音采集电子成品套件21(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • COLMAP 3.9 实战:无人机航拍图像三维重建,从 500 张图到稠密点云全流程
  • DataEase高危漏洞复现:从H2数据库注入到RCE攻击链深度解析
  • C语言学习学习笔记20260704-中缀表达式求值(双栈法)
  • 乡村振兴 + 零碳民生稿:叁仟光伏智慧灯杆,点亮杭州共富乡村绿色数字路
  • Node.js性能优化实战:从瓶颈分析到集群扩展
  • ICM-42688-P运动传感器与PIC18F4553的工业应用解析
  • Python特征工程实战:从数据清洗到模型提效的完整流程
  • uos-network-exporter配置指南:10个关键参数优化网络监控性能
  • AI代码代理Claude Code实战指南:从安装到项目开发全流程
  • Qt Quick 常用控件入门:Window、Button、CheckBox 与 RadioButton
  • 开源项目C++ Workflow学习
  • AI时代依然受用:那些越过越好的人,都学会了这件事。
  • [MAF预定义ChatClient中间件-04]ReducingChatClient——精减对话历史又不丢失基本语义
  • 2026年避坑攻略:如何挑选性价比高的外墙保温装饰一体板厂家