.NET应用架构设计—工作单位模式(摆脱程序代码的重要思想,反击DDD)

.NET应用架构设计—工作单位模式(摆脱程序代码的重要思想,反击DDD)

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。

阅读文件夹:

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

1.背景介绍

一直都在谈论面向对象开发。可是开发企业应用系统时。使用面向对象开发最大的问题就是在于,多个对象之间的互操作须要涉及数据库操作。两个业务逻辑对象彼此之间须要互相调用,假设之间的互相操作是在一个业务事务范围内的,非常easy完毕,可是假设本次业务逻辑操作涉及到多个业务对象一起协作完毕时问题就来了。

在以往,我们使用过程式的代码(事务脚本模式),将全部与本次业务事务范围内相关的全部逻辑都写在一个大的代码中,就算你适当的提取反复代码。效果也不大,由于你永远都摆脱不了夸多个对象互相操作的困境。怎样确认你是否在这个困境中,你仅仅要看你的全部事务操作的入口都仅仅有一个业务方法。

比方当你加入一个订单的时候,你同一时候将订单尾随的商品都一起在“加入订单”的方法中处理的,而不是在另外一个“加入订单商品”的方法中,这两个方法位于不同的表模块类中。

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

2.过程式代码的困境

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

我之前也写过非常多组件、框架,尽管谈不上什么复杂的东西,可是给我的经验和感悟就是,怎样将其仔细的设计粒度用在企业应用系统中。怎样进行复杂而仔细的OO设计开发。事实上。假设我们不可以打破过程式代码的格局,那么看再多的OO知识也是心有余而力不足,反而会让你产生非常多负面的情绪(由于我有过这个经历)。

事实上我们还是缺少正确的方法而已。本文中UnitOfWork模式将帮助我们走出过程式的业务逻辑,走向起码的面向对象开发。

有了UnitOfWork你能够任意使用Table module 、Activa Record、Domin Driven 模式,并且你能够依据自己的项目须要将其在大的布局上进行SOA划分(CQRS),让各个模式在各自适合的场景中发挥极致。

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

这里我们依旧使用简单的订单购物业务作为演示样例来讲,毕竟大家都懂得这部分的的业务概念。

本实例业务层使用Active Record模式。

namespace OrderManager.Business
{
    using System.Collections.Generic; 

    public partial class Order
    {
        public long OId { get; set; } 

        public List<OrderProducts> Products { get; set; }
    }
}

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

namespace OrderManager.Business
{
    public partial class Order
    {
        public bool CheckOrder()
        {
            //运行部分业务验证工作
            if (this.OId <= 0) return false; 

            return true;
        }
    }
}

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

namespace OrderManager.Business
{
    public partial class OrderProducts
    {
        public long OrderId { get; set; } 

        public long PId { get; set; } 

        public float Price { get; set; }
    }
}

订单商品部分字段。

namespace OrderManager.Business
{
    public partial class OrderProducts
    {
        public bool CheckProducts()
        {
            //运行部分业务验证工作
            if (this.OrderId <= 0) return false; 

            return true;
        }
    }
}

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

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

namespace OrderManager
{
    using OrderManager.Business;
    using OrderManager.DataSource; 

    public class OrderManagerController : ControllerBase
    {
        public bool AddOrder(Order order)
        {
            using (UnitOfWork unitOfWork = new UnitOfWork())
            {
                order.CheckOrder();//运行业务检查 

                order.Products.ForEach(item =>
                {
                    item.CheckProducts();//运行每一个活动记录对象的业务检查。这里也能够使用表模块来处理。
                }); 

                OrderGateway orderGateway = new OrderGateway(unitOfWork);
                var orderDbResult = orderGateway.AddOrder(order);//第一个数据库表操作 

                OrderProductsGateway productGateway = new OrderProductsGateway(unitOfWork);
                var productDbResult = productGateway.AddOrderProducts(order.Products);//第二个数据库表操作 

                if (orderDbResult && productDbResult)
                {
                    if (unitOfWork.Commit())
                    {
                        this.SendOrderIntegrationMssage(order);//发送成功集成订单消息 

                        return true;
                    } 

                    this.PushOrderProcessQueue(order);//将本次订单发送到处理队列中
                    return false;
                } 

                this.LogBusinessException(order);//记录一个业务处理异常LOG,以备排查问题。

return false; } } }}

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

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

namespace OrderManager.DataSource
{
    public abstract class GatewayBase
    {
        protected UnitOfWork UnitOfWork { get; private set; } 

        public GatewayBase(UnitOfWork unit)
        {
            this.UnitOfWork = unit;
        } 

        public bool Commit()
        {
            return this.UnitOfWork.Commit();
        } 

        public void Rollback()
        {
            this.UnitOfWork.Rollback();
        }
    }
}

这是一个表入口基类。

namespace OrderManager.DataSource
{
    using OrderManager.Business; 

    public class OrderGateway : GatewayBase
    {
        public OrderGateway(UnitOfWork unit) : base(unit) { } 

        public bool AddOrder(Order order)
        {
            //这里能够使用你所熟悉的拼接SQL的方式直接操作数据库。而不须要ORM。
            return true;
        }
    }
}

namespace OrderManager.DataSource
{
    using OrderManager.Business;
    using System.Collections.Generic; 

    public class OrderProductsGateway : GatewayBase
    {
        public OrderProductsGateway(UnitOfWork unit) : base(unit) { } 

        public bool AddOrderProducts(List<OrderProducts> products)
        {
            //这里能够使用你所熟悉的拼接SQL的方式直接操作数据库,而不须要ORM。
            return true;
        }
    }
}

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

namespace OrderManager.DataSource
{
    using System; 

    public class UnitOfWork : IDisposable
    {
        public void Dispose()
        {
            throw new NotImplementedException();
        } 

        public bool Commit()
        {
            return true;
        } 

        public void Rollback()
        {
            //
        }
    }
}

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

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

4.总结

活动记录模式+表入口模式+工作单元模式,事实上我认为能够非常好的处理中小型业务逻辑。随着如今SOA化架构,非常少再有多大的项目在一个解决方式里面。

最后还是那句话。提供一个參考资料,假设有兴趣能够进一步交流详细的设计,因为时间关系文章就到这里了,谢谢大家。

作者:王清培

出处:http://blog.csdn.net/wangqingpei557

本文版权归作者和CSDN共同拥有,欢迎转载,但未经作者允许必须保留此段声明,且在文章页面明显位置给出原文连接。否我们保留追究法律责任的权利。

版权声明:本文博主原创文章,博客,未经同意不得转载。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117037.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 素数判断算法(高效率)「建议收藏」

    素数判断算法(高效率)「建议收藏」chuanbindeng的素数判断算法关于素数的算法是信息学竞赛和程序设计竞赛中常考的数论知识,在这里我跟大家讲一下寻找一定范围内素数的几个算法。看了以后相信对大家一定有帮助。   正如大家都知道的那样,一个数n如果是合数,那么它的所有的因子不超过sqrt(n)–n的开方,那么我们可以用这个性质用最直观的方法来求出小于等于n的所有的素数。   num=0;

    2022年6月18日
    31
  • 2021年五面蚂蚁,java必背代码入门[通俗易懂]

    2021年五面蚂蚁,java必背代码入门[通俗易懂]一面(个人感觉回答得还不错)1.自我介绍2.说项目,项目问的非常深(本人提到之前做过的一篇关于FULLGC的问题定位和优化的项目以及一个多并发的项目)2.1对于自己产于过项目的系统定位是否清楚?2.2对于系统的各个模块是否清楚?2.3每个接口的tps?2.4对于上下游系统的依赖?2.5对于使用到的中间件、框架是否清楚?3.你觉得你做的项目中最有亮点的事情?4.memcacheredis同类中间的差异、优缺点?使用注意点有哪些?memcache可以存储的

    2022年7月8日
    23
  • phpstorm最新激活码【中文破解版】「建议收藏」

    (phpstorm最新激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.html…

    2022年3月26日
    64
  • Oracle 函数编写[通俗易懂]

    Oracle 函数编写[通俗易懂]CREATEORREPLACEFUNCTIONf_homestay_count(wkt_polyCLOB)RETURNNUMBERISresultNUMBER;BEGIN SELECT COUNT(*)INTOresult FROM HOMESTAY_BASICT WHERE sdo_anyinteract( T.geom_po…

    2022年7月17日
    19
  • cpu用户态和内核态区别_内核拷贝数据到用户态

    cpu用户态和内核态区别_内核拷贝数据到用户态这里写目录标题内核态与用户态的区别用户态到内核态的切换操作系统需要两种CPU状态:内核态(KernelMode):运行操作系统程序,操作硬件用户态(UserMode):运行用户程序操作系统有三个特权级别:R0、R1、R2和R3。R0相当于内核态,R3相当于用户态,不同级别能够运行不同的指令集合。内核态与用户态的区别用户态的程序运行在3级特权级上,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态。内核态的程序运行在0级特权级上。处于用户态执行时

    2022年9月18日
    1
  • Java面向对象三大特性学习总结

    Java面向对象三大特性学习总结面向对象的三大特性:封装、继承、多态将对象的属性和实现细节隐藏起来,不让外部程序直接进行访问,将属性私有化,仅对外公开接口,让外部程序通过类提供的方法来对隐藏信息进行访问和操作。好处是外部程序只能通过类规定的方法对数据进行访问,避免外界程序对类内部属性进行破坏。

    2022年7月25日
    8

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号