.NET应用架构设计—工作单元模式(摆脱过程式代码的重要思想,代替DDD实现轻量级业务)

阅读目录:

  • 1.背景介绍
  • 2.过程式代码的真正困境
  • 3.工作单元模式的简单示例
  • 4.总结

1.背景介绍

一直都在谈论面向对象开发,但是开发企业应用系统时,使用面向对象开发最大的问题就是在于,多个对象之间的互操作需要涉及数据库操作。两个业务逻辑对象彼此之间需要互相调用,如果之间的互相操作是在一个业务事务范围内的,很容易完成,但是如果本次业务逻辑操作涉及到多个业务对象一起协作完成时问题就来了。

在以往,我们使用过程式的代码(事务脚本模式),将所有与本次业务事务范围内相关的所有逻辑都写在一个大的代码中,就算你适当的提取重复代码,效果也不大,因为你永远都摆脱不了夸多个对象互相操作的困境。如何确认你是否在这个困境中,你只要看你的所有事务操作的入口都只有一个业务方法。比如当你添加一个订单的时候,你同时将订单跟随的商品都一起在“添加订单”的方法中处理的,而不是在另外一个“添加订单商品”的方法中,这两个方法位于不同的表模块类中。

本章将介绍一个模式,此模式专门用来在开发企业应用系统时,协调多个业务对象在一个业务事务范围内,保证一个完整的事务。

2.过程式代码的困境

其实开发应用系统与开发某个框架或者组件之间的最大区别就是需要考虑数据的持久化,而持久化的逻辑也是和业务逻辑息息相关的,某个方法的最后动作就有可能是添加一行数据或者更新一个字段。而非应用系统的代码往往在最后的时候才去统一刷新最终的持久化文件,而且此类程序很少存在事务性数据操作。就算有,使用内存事务处理也是比较简单的,不需要考虑那么多的服务端的事情。

我之前也写过很多组件、框架,虽然谈不上什么复杂的东西,但是给我的经验和感悟就是,如何将其细致的设计粒度用在企业应用系统中,如何进行复杂而细致的OO设计开发。其实,如果我们不能够打破过程式代码的格局,那么看再多的OO知识也是心有余而力不足,反而会让你产生很多负面的情绪(因为我有过这个经历)。

其实我们还是缺少正确的方法而已,本文中UnitOfWork模式将帮助我们走出过程式的业务逻辑,走向起码的面向对象开发。有了UnitOfWork你可以随意使用Table module 、Activa Record、Domin Driven 模式,而且你可以根据自己的项目需要将其在大的布局上进行SOA划分(CQRS),让各个模式在各自适合的场景中发挥极致。

3.工作单元模式的简单示例

这里我们依然使用简单的订单购物业务作为示例来讲,毕竟大家都懂得这部分的的业务概念。本实例业务层使用Active Record模式。

 1 namespace OrderManager.Business
 2 {
 3     using System.Collections.Generic;
 4
 5     public partial class Order
 6     {
 7         public long OId { get; set; }
 8
 9         public List<OrderProducts> Products { get; set; }
10     }
11 }

Order活动记录对象的字段部分。

 1 namespace OrderManager.Business
 2 {
 3     public partial class Order
 4     {
 5         public bool CheckOrder()
 6         {
 7             //执行部分业务验证工作
 8             if (this.OId <= 0) return false;
 9
10             return true;
11         }
12     }
13 }

Order活动记录对象主体,纯粹为了演示而用,包含了一个简单的判断业务逻辑。

 1 namespace OrderManager.Business
 2 {
 3     public partial class OrderProducts
 4     {
 5         public long OrderId { get; set; }
 6
 7         public long PId { get; set; }
 8
 9         public float Price { get; set; }
10     }
11 }

订单商品部分字段。

 1 namespace OrderManager.Business
 2 {
 3     public partial class OrderProducts
 4     {
 5         public bool CheckProducts()
 6         {
 7             //执行部分业务验证工作
 8             if (this.OrderId <= 0) return false;
 9
10             return true;
11         }
12     }
13 }

每一个商品都包含了自己的逻辑验证。

我们接着看一下应用层入口方法是如何协调两个活动记录对象之间的业务操作和数据存储的。

 1 namespace OrderManager
 2 {
 3     using OrderManager.Business;
 4     using OrderManager.DataSource;
 5
 6     public class OrderManagerController : ControllerBase
 7     {
 8         public bool AddOrder(Order order)
 9         {
10             using (UnitOfWork unitOfWork = new UnitOfWork())
11             {
12                 order.CheckOrder();//执行业务检查
13
14                 order.Products.ForEach(item =>
15                 {
16                     item.CheckProducts();//执行每个活动记录对象的业务检查,这里也可以使用表模块来处理。
17                 });
18
19                 OrderGateway orderGateway = new OrderGateway(unitOfWork);
20                 var orderDbResult = orderGateway.AddOrder(order);//第一个数据库表操作
21
22                 OrderProductsGateway productGateway = new OrderProductsGateway(unitOfWork);
23                 var productDbResult = productGateway.AddOrderProducts(order.Products);//第二个数据库表操作
24
25                 if (orderDbResult && productDbResult)
26                 {
27                     if (unitOfWork.Commit())
28                     {
29                         this.SendOrderIntegrationMssage(order);//发送成功集成订单消息
30
31                         return true;
32                     }
33
34                     this.PushOrderProcessQueue(order);//将本次订单发送到处理队列中
35                     return false;
36                 }
37
38                 this.LogBusinessException(order);//记录一个业务处理异常LOG,以备排查问题。
39                 return false;
40             }
41         }
42     }
43 }

为了简单演示示例,我直接使用实例化的方式来构造数据访问对象,实际使用时可以使用IOC工具来动态注入。

我们接着看一下数据层代码,数据层我使用表入口模式。

 1 namespace OrderManager.DataSource
 2 {
 3     public abstract class GatewayBase
 4     {
 5         protected UnitOfWork UnitOfWork { get; private set; }
 6
 7         public GatewayBase(UnitOfWork unit)
 8         {
 9             this.UnitOfWork = unit;
10         }
11
12         public bool Commit()
13         {
14             return this.UnitOfWork.Commit();
15         }
16
17         public void Rollback()
18         {
19             this.UnitOfWork.Rollback();
20         }
21     }
22 }

这是一个表入口基类。

 1 namespace OrderManager.DataSource
 2 {
 3     using OrderManager.Business;
 4
 5     public class OrderGateway : GatewayBase
 6     {
 7         public OrderGateway(UnitOfWork unit) : base(unit) { }
 8
 9         public bool AddOrder(Order order)
10         {
11             //这里可以使用你所熟悉的拼接SQL的方式直接操作数据库,而不需要ORM。
12             return true;
13         }
14     }
15 }
 1 namespace OrderManager.DataSource
 2 {
 3     using OrderManager.Business;
 4     using System.Collections.Generic;
 5
 6     public class OrderProductsGateway : GatewayBase
 7     {
 8         public OrderProductsGateway(UnitOfWork unit) : base(unit) { }
 9
10         public bool AddOrderProducts(List<OrderProducts> products)
11         {
12             //这里可以使用你所熟悉的拼接SQL的方式直接操作数据库,而不需要ORM。
13             return true;
14         }
15     }
16 }

这是两个表入口对象,其实这部分代码是大家都比较熟悉的,所以我这里省略了,你可以直接拼接SQL语句来插入数据库。

 1 namespace OrderManager.DataSource
 2 {
 3     using System;
 4
 5     public class UnitOfWork : IDisposable
 6     {
 7         public void Dispose()
 8         {
 9             throw new NotImplementedException();
10         }
11
12         public bool Commit()
13         {
14             return true;
15         }
16
17         public void Rollback()
18         {
19             //
20         }
21     }
22 }

 

UnitOfWrok对象其实就是对数据库对象的System.Data.Common.DbConnection对象的封装,这里你可以使用你熟悉的方式来构造这个数据库连接对象和开启事务。

其实值得我们去欣赏的是应用控制器中的代码,在这里很协调的处理各个逻辑,最后记录下一些必要的日志和发送一些集成消息。你是不是发现你完全可以不使用DDD也可以处理部分业务系统了。

4.总结

活动记录模式+表入口模式+工作单元模式,其实我觉得可以很好的处理中小型业务逻辑,随着现在SOA化架构,很少再有多大的项目在一个解决方案里面。

最后还是那句话,提供一个参考资料,如果有兴趣可以进一步交流具体的设计,由于时间关系文章就到这里了,谢谢大家。

 

作者:王清培

出处:http://www.cnblogs.com/wangiqngpei557/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

时间: 2024-10-29 00:59:46

.NET应用架构设计—工作单元模式(摆脱过程式代码的重要思想,代替DDD实现轻量级业务)的相关文章

Contoso学习(九) 实现仓储和工作单元模式

在上一次的教程中,你已经使用继承来消除在 Student 和 Instructor 实体之间的重复代码.在这个教程中,你将要看到使用仓储和工作单元模式进行增.删.改.查的一些方法.像前面的教程一样,你将要修改已经创建的页面中代码的工作方式,而不是新创建的页面. 9-1  仓储和工作单元模式 仓储和工作单元模式用来在数据访问层和业务逻辑层之间创建抽象层.实现这些模式有助于隔离数据存储的变化,便于自动化的单元测试或者测试驱动的开发 ( TDD ). 在这个教程中,你将要为每个实体类型实现一个仓储类.

Contoso 大学 - 9 - 实现仓储和工作单元模式

原文 Contoso 大学 - 9 - 实现仓储和工作单元模式 By Tom Dykstra, Tom Dykstra is a Senior Programming Writer on Microsoft's Web Platform & Tools Content Team. 原文地址:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-

.NET应用架构设计—表模块模式与事务脚本模式的代码编写

阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是胡子眉毛一把抓.现在有一个现象是什么呢,项目的结构从表面上看是很不错,层分的很合理,其实对业务系统来说也就那么几种层设计方法,但是现在很多项目的逻辑架构的设计不是理想,有很多概念大家并不是很了解,当然也许每个人对技术的追求不同罢了.不管你追求不追求,事实我们还是要去往正确的方向努力才对的. 很多人包

.NET架构设计、框架设计系列文章总结

从事.NET开发到现在已经有七个年头了.慢慢的可能会很少写.NET文章了.不知不觉竟然走了这么多年,热爱.NET热爱c#.突然想对这一路的经历进行一个总结. 是时候开始下一阶段的旅途,希望这些文章可以在发挥点价值作用.     架构设计: ElasticSearch大数据分布式弹性搜索引擎使用 (推荐) DDD实施经验分享-价值导向.从上往下进行(圈内第一个吃螃蟹DDD实施方案)(推荐) 软件工程-思考项目开发那些事(一)(推荐) SOA架构设计经验分享-架构.职责.数据一致性(推荐) .NET

.NET应用架构设计—适当使用活动记录模式代替领域模型模式

阅读目录: 1.背景介绍 2.简单介绍领域模型模式.活动记录模式 3.活动记录模式的简单示例及要点 4.总结 1.背景介绍 对软件开发方法论有兴趣的博友应该发现最近"领域驱动设计"慢慢的被人发现被人实践起来,园子里也慢慢有了DDD的学习气氛和宝贵实战经验的分享.其实之前我也痴迷于DDD,为什么会痴迷于它并不是因为它是所谓的新技术,也不是因为各种对它的炒作,而是我觉得我找到了能解放我们进行企业业务系统开发的方法论. DDD可以很好的指导我们开发可靠的软件系统,尤其是现在的企业业务复杂多变

微软Visual Studio 2010架构设计功能应用

随着软件开发日趋国际化,对软件的质量要求和管理也随之增高.微软看到了应用程序生命周期管理在业界逐渐被接受认可的趋势.在微软 VS2010(Visual Studio 2010 Ultimate)中,可以利用各种工具辅助每个关键环节进行管理(ALM)是其重要特性.Visual Studio经过近十年左右的发展,已经不再是仅仅面向某一个角色(开发人员)的工具,而是要服务于软件开发过程中的所有不同的角色(开发人员.测试人员.架构师.项目经理等),使其覆盖在整个软件开发生命周期(SDLC)中,本文将重点

架构设计 - 自动化运维之架构设计六要点

运维自动化是我们所渴望获得的,但是我们在一味强调自动化能力时,却忽略了影响自动化落地的一个关键因素.那便是跟运维朝夕相处,让人又爱又恨的业务架构. 因为业务架构是决定运维效率和质量的关键因素之一,所以我想跟大家一起聊一下怎么样的架构设计是对运维友好的.结合这些年在腾讯遇到的业务架构和做运维规划时对业务非功能规范的思考,我们可以把面向运维的架构设计分成六大设计要点. 要点一:架构独立 任何架构的产生都是为了满足特定的业务诉求,如果我们在满足业务要求的同时,能够兼顾运维对架构管理的非功能性要求.那么

四层架构设计驱动模型在CKM中的实践

写在前面:本文纯属个人想法和http://www.aliyun.com/zixun/aggregation/7335.html">经验总结,如转载请注明出处,如有雷同纯属巧合 (: 1. 一般的架构设计流程 所有的软件开发方法都要解决从需求到实践的转换问题,为了提高软件的质量,前辈们提出了需求分析工程和各种建模技术,但是在需求和设计之间还是很难逾越,也就是说缺乏能够反映做决策的中间过程,于是软件架构设计应运而生. 对于架构设计人们已经提出了许多方法,分类为:工件驱动的方法:用例驱动的法:模

针对架构设计的几个痛点,我总结出的架构原则和模式

[编者的话]本文来自Firat Atagun的<架构演化中的软件设计原则>,文中给出了软件架构演化过程中出现的4种经典架构,就每种架构,分析了其主要特点并在几个度量维度给出结论.在文章的最后,Firat Atagun给出了4种架构的多维对比.本文的完整演讲稿是架构演化中的软件设计原则. 1 分层架构 分层架构是最常见的架构,也被称为n层架构.多年以来,许多企业和公司都在他们的项目中使用这种架构,它已经几乎成为事实标准,因此被大多数架构师.开发者和软件设计者所熟知. 分层架构中的层次和组件是水平