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

简介: 阅读目录: 1.背景介绍 2.简单介绍表模块模式、事务脚本模式 3.正确的编写表模块模式、事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是胡子眉毛一把抓。

阅读目录:

  • 1.背景介绍
  • 2.简单介绍表模块模式、事务脚本模式
  • 3.正确的编写表模块模式、事务脚本模式的代码
  • 4.总结

1.背景介绍

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

很多人包括我自己在内,都是写过很多年的过程式的代码,层对我当年来说就是个摆设而已,最典型的问题就是我们总是将表模块模式和事物脚本模式一起混着使用,什么意思呢,就是说我们都会使用一些代码生成器来根据数据库中的表来生成三层架构中的业务层和数据层,有些比较好的代码生成器也可以帮你把UI层中的部分视图也生成好,确实很强大,有些场合下这是一中最合适的过程。

但是现在的系统已经不在是那样的了,其中重要的一点就是业务复杂了,如果我们还稀里糊涂的编写着代码,最后只会成为你或者团队的技术债务。

2.简单介绍表模块模式、事务脚本模式

我们简单了解一下这里所谓的“表模块模式、”事务脚本模式“到底是什么样子的模式,最关键是你也许就知道了你目前所使用的业务层架构风格是什么模式,强调一下“表模块模式”、“事物脚本模式”都是业务层的构架模式

表模块模式:

简单讲就是你数据库中的每个表对应着业务层中的一个对象定义,如果你有一个Product表,那么你在Business Layer中就有一个Product.cs文件,当然这不是绝对的,你也可以将库中的视图也定义一个类型,如,OrderProduct.cs,也是可以的。然后每个类中的所处理的逻辑都是跟这张表相关的,你在Product.cs中的代码就不要包含Order.cs中的代码了。目前来看是有的,因为现在大部分的项目都是在写着使用过程式的代码,也就是事物脚本模式,这样难免会将其他类型中的代码写到本类中。

事物脚本模式:

事务脚本模式就是过程式的代码,只不过它的指标就是每一个代码段独立完成一个业务单元,而不是到处都是过程代码,事物脚本模式还是很强调逻辑的统一性的。

使用此模式进行写代码时,你就不要单纯的使用数据库中的表名来定义业务类了,因为你是使用事务脚本模式的,你需要站在业务角度来规划你的业务层中大概包含哪些业务概念,然后使用这个业务概念来命名你的类。比如:UserOrder,UserOrder,类似这样的定义,当然这里只是个假设而已,你不要站在数据库的脚本来设计业务层就行了,这样你就起码不会使用到很细粒度的类型,哪怕下一次迭代进行重构也是可以的。

3.正确的编写表模块模式、事务脚本模式的代码

这篇文章的重点就是本节,我们将了解一下这两种模式的代码到底该如何编写。

说代码如何编写似乎有点让人觉得不是很礼貌,其实我们大部分的代码写的都是正确的,但是如果我们将有些代码稍微的罗一下位置就会明显不一样。

我们来看一个小例子,例子很简单,有两个类型Order、Product,用来完成一般的业务逻辑处理,我们通过不同的模式来看到底如何使用

现在的事务脚本模式的代码:

namespace Business
{
    public class Order
    {
        [Serializable]
        public class OrderField
        {
            public string OId { get; set; } 

            [NonSerialized]
            public List<Product.ProductField> Products { get; set; }
        } 

        public OrderField Field { get; set; } 

        public void AddOrder(OrderField orderField)
        {
            var sendMQOrders = new List<string>();//合格的产品ID集合 

            orderField.Products.ForEach(product =>
            {
                if (product.Price <= 20)//不满足条件
                    return; 

                sendMQOrders.Add(product.PId);//满足条件
            }); 

            MqHelper.SendOrder(orderField, sendMQOrders);//发送订单数据实体到队列中
        }
    }
}

Order业务类中有一个添加Order的方法,在该方法中是一些简单的业务逻辑处理,判断了要添加的这个商品的价格是否大于20块钱。最后使用过滤下来的商品ID作为本订单的有效产品。

这就是我们目前使用的代码风格,这里有两个问题,第一:类的命名,Order的概念太大了,没有进行细化,显然不是按照事务脚本模式来进行设计的而是按照表模块方式进行划分的,还有如果我就算你是按照事物脚本模式来设计的,我就喜欢定义大的概念难道不对吗?也可以,但是在Order的定义里面明确使用了Product类型下的子类型,也就说这里出现了两个独立的业务范围,正常的理解肯定是按照表模块模式来设计的。第二:如果是按照表模块模式来设计的,因为根据这个对象的命名很明显是此模式,但是仔细阅读一下代码发现职责还是有点不清晰,在Order.AddOrder(OrderField orderField)方法中,有Product的逻辑在里面if (product.Price <= 20),当然这里是业务逻辑比较简单的情况下的,如果是业务比较复杂的时候,就会出现大量的代码在Order类中,到最后就会发现我们已经分不清此业务架构到底是使用何种模式来设计的。

我们有两个做法,第一个做法是:将其改成事务脚本模式,让类的命名和设计泛化,也就是说不要定义那么明显的数据库中的表名字,不要清晰的区分Order和Product两个职责。第二个做法是:将其改成表模块模式,将每个类型中的业务逻辑完全清晰化,将if (product.Price <= 20)提取到Product业务类中去,然后在应用控制器中先处理此逻辑后在调用Order.AddOrder(OrderField orderField)方法进行处理,这个方法里面只做跟当前类型相关的逻辑,参考的依据就是一旦你发现你所写的代码里出现了别的类型时,此时你应该告诉自己有可能这个地方需要重构职责。

两个方法来移动此逻辑:

1:(将if (product.Price <= 20)封进Price属性中)

namespace Business
{
    public class Order
    {
        [Serializable]
        public class OrderField
        {
            public string OId { get; set; } 

            [NonSerialized]
            public List<Product.ProductField> Products { get; set; }
        } 

        public OrderField Field { get; set; } 

        public void AddOrder(OrderField orderField)
        {
            var sendMQOrders = new List<string>();//合格的产品ID集合 

            orderField.Products.ForEach(product =>
            {
                if (product.Price.IsValid()/*执行价格判断*/) return; 

                sendMQOrders.Add(product.PId);//满足条件
            }); 

            MqHelper.SendOrder(orderField, sendMQOrders);//发送订单数据实体到队列中
        }
    }
}

此方法有个问题就是商品的价格没有收到订单的控制,这看具体的业务需要了,我只是个假设。

2:完全独立的过滤无效产品的方法

namespace Business
{
    public class OrderApplicationController
    {
        public void SubmitOrder(Order.OrderField field)
        {
            field.Products = new Product().FilterProduct(field.Products);//先过滤 

            new Order().AddOrder(field);//在添加
        }
    }
}

我们先调用Product中的业务方法过滤无效的商品,然后在进行订单添加操作,这样我们就将各自的职责放到自己的位置去。

4.总结

还是那句话,这只是我学习过程中的一点小小的领悟,给大家一个参考的资料,希望对你有用,谢谢。

 

作者:王清培

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

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

目录
相关文章
|
1月前
|
C# Android开发 iOS开发
2025年全面的.NET跨平台应用框架推荐
2025年全面的.NET跨平台应用框架推荐
86 23
|
1月前
|
容灾 网络协议 数据库
云卓越架构:云上网络稳定性建设和应用稳定性治理最佳实践
本文介绍了云上网络稳定性体系建设的关键内容,包括面向失败的架构设计、可观测性与应急恢复、客户案例及阿里巴巴的核心电商架构演进。首先强调了网络稳定性的挑战及其应对策略,如责任共担模型和冗余设计。接着详细探讨了多可用区部署、弹性架构规划及跨地域容灾设计的最佳实践,特别是阿里云的产品和技术如何助力实现高可用性和快速故障恢复。最后通过具体案例展示了秒级故障转移的效果,以及同城多活架构下的实际应用。这些措施共同确保了业务在面对网络故障时的持续稳定运行。
|
2月前
|
NoSQL 关系型数据库 MySQL
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
201 56
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
|
2月前
|
运维 Cloud Native 持续交付
深入理解云原生架构及其在现代企业中的应用
随着数字化转型的浪潮席卷全球,企业正面临着前所未有的挑战与机遇。云计算技术的迅猛发展,特别是云原生架构的兴起,正在重塑企业的IT基础设施和软件开发模式。本文将深入探讨云原生的核心概念、关键技术以及如何在企业中实施云原生策略,以实现更高效的资源利用和更快的市场响应速度。通过分析云原生架构的优势和面临的挑战,我们将揭示它如何助力企业在激烈的市场竞争中保持领先地位。
|
3月前
|
运维 Kubernetes Docker
深入理解容器化技术及其在微服务架构中的应用
深入理解容器化技术及其在微服务架构中的应用
108 1
|
3月前
|
Cloud Native 安全 持续交付
深入理解微服务架构及其在现代软件开发中的应用
深入理解微服务架构及其在现代软件开发中的应用
112 32
|
3月前
|
监控 持续交付 API
深入理解微服务架构及其在现代应用开发中的应用
深入理解微服务架构及其在现代应用开发中的应用
47 4
|
3月前
|
边缘计算 监控 自动驾驶
揭秘云计算中的边缘计算:架构、优势及应用场景
揭秘云计算中的边缘计算:架构、优势及应用场景
|
3月前
|
存储 监控 API
深入解析微服务架构及其在现代应用中的实践
深入解析微服务架构及其在现代应用中的实践
100 12
|
3月前
|
监控 物联网 持续交付
深入理解微服务架构及其在现代软件开发中的应用
深入理解微服务架构及其在现代软件开发中的应用
55 0

热门文章

最新文章