表模块和领域模型比,有两个显著区别:

1:表模块中的类和数据库表基本一一对应,而领域模型则无此要求;

2:表模块中的类的对象处理表中的所有记录,而领域模型的一个对象代表表中的一行记录;

一般情况下,我们可以基于第二点来严格区分你的设计是表模块的,还是领域模型的。如:如果我们有许多订单,则领域模型的每一个订单都有一个对象,而表模块只有一个对象来处理所有订单(注意,这里的类,都是指业务逻辑层的类,而不是实体类。表模块的类的对象和常规的领域模型的对象很类似,但是关键区别是:它没有标识符来标出它所代表的实体对象)。举例来说,如果要查询某个订单,表模块会像这样进行编码:

anOrderModule.GetOrder(string orderId);

因为表模块只有一个对象来处理所有订单,所以表模块可以是一个实例,也可以是一个只包含静态方法的静态类。

表模块 的代码和 事务脚本类似:

class TableModel
{
    protected DataTable table;
   
    protected TableModel(DataSet ds, string tableName)
    {
        table = ds.Tables[tableName];
    }
}

class Contract : TableModel
{
    public Contract(DataSet ds) : base (ds, "Contracts")
    {
    }
   
    public DataRow this[long id]
    {
        get
        {
            string filter = "ID=" + id;
            return table.Select(filter)[0];
        }
    }
   
    public void CalculateRecognitions(long contactId)
    {
        DataRow contractRow = this[contactId];
        double amount = (double)contractRow["amount"];
        RevenueRecognition rr = new RevenueRecognition(table.DataSet);
        Product prod = new Product(table.DataSet);
        long prodId = GetProductId(contactId);
       
        if(prod.GetProductType(prodId) == "W")
        {
            rr.Insert(contactId, amount, (DateTime)GetWhenSigned(contactId));
        }else if(prod.GetProductType(prodId) == "S")    // 电子表格类
        {
            // the sql "INSERT INTO REVENUECONGNITIONS (CONTRACT,AMOUNT,RECOGNIZEDON) VALUES (?,?,?)"
            DateTime dateSigned = (DateTime)GetWhenSigned(contactId);
            rr.Insert(contactId, amount / 3, dateSigned);
            rr.Insert(contactId, amount / 3, dateSigned.AddDays(60));
            rr.Insert(contactId, amount / 3, dateSigned.AddDays(90));
        }else if(prod.GetProductType(prodId) == "D")    // 数据库
        {   
            DateTime dateSigned = (DateTime)GetWhenSigned(contactId);
            rr.Insert(contactId, amount / 3, dateSigned);
            rr.Insert(contactId, amount / 3, dateSigned.AddDays(30));
            rr.Insert(contactId, amount / 3, dateSigned.AddDays(60));
        }
    }
   
    private long GetProductId(long contactId)
    {
        return (long)this[contactId]["ProductId"];
    }
   
    private DateTime GetWhenSigned(long contactId)
    {
        return (DateTime)this[contactId]["DateSigned"];
    }
}

class RevenueRecognition : TableModel
{
    public RevenueRecognition(DataSet ds) : base (ds, "RevenueRecognitions")
    {
    }
   
    public long Insert(long contactId, double amount, DateTime whenSigned)
    {
        DataRow newRow = table.NewRow();
        long id = GetNextId();
        newRow["Id"] = id;
        newRow["ContactId"] = contactId;
        newRow["Amount"] = amount;
        newRow["DateSigned"] = whenSigned;
        table.Rows.Add(newRow);
        return id;
    }
   
    // 得到哪天前入账了多少
    public double RecognizedRevenue(long contractNumber, DateTime asOf)
    {
        // the sql "SELECT AMOUNT FROM REVENUECONGNITIONS WHERE CONTRACT=? AND RECOGNIZEDON <=?";
        string filter = string.Format("ContactId={0} AND date <=#{1:d}", contractNumber, asOf);
        DataRow[] rows = table.Select(filter);
        double r = 0.0;
        foreach(DataRow dr in rows)
        {
            r += (double)dr["AMOUNT"];
        }
       
        return r;
    }
   
    private long GetNextId()
    {
        throw new Exception();
    }
}

class Product : TableModel
{
    public Product(DataSet ds) : base (ds, "Products")
    {
    }
   
    public DataRow this[long id]
    {
        get
        {
            string filter = "ID=" + id;
            return table.Select(filter)[0];
        }
    }
   
    public string GetProductType(long productId)
    {
        return (string)this[productId]["Type"];
    }
}

架构模式逻辑层模式之:表模块(Table Model)的更多相关文章

  1. 架构设计--逻辑层 vs 物理层

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 Layer 和Tier都是层,但是他们所表现的含义不同,Tier指的是软件系统中物理 ...

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

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

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

    阅读目录: 1.背景介绍 2.简单介绍领域模型模式.活动记录模式 3.活动记录模式的简单示例及要点 4.总结 1.背景介绍 对软件开发方法论有兴趣的博友应该发现最近“领域驱动设计”慢慢的被人发现被人实 ...

  4. 【C#|.NET】从细节出发(三) 逻辑层事务和page object模式

    一. 业务逻辑层的事务问题 如果你的程序分层清晰并且系统禁用复杂存储过程,那么在DA中的职责比较单一.程序的逻辑通过BLL调用各种不同模块的DA来实现数据操作.如果当需要不同模块在一个事务的时候,问题 ...

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

    阅读目录: 1.背景介绍 2.过程式代码的真正困境 3.工作单元模式的简单示例 4.总结 1.背景介绍 一直都在谈论面向对象开发,但是开发企业应用系统时,使用面向对象开发最大的问题就是在于,多个对象之 ...

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

    阅读文件夹: 1.背景介绍 2.过程式代码的真正困境 3.工作单元模式的简单演示样例 4.总结 1.背景介绍 一直都在谈论面向对象开发.可是开发企业应用系统时.使用面向对象开发最大的问题就是在于,多个 ...

  7. 模型-视图-控制器模式(MVC模式,10种常见体系架构模式之一)

    一.简介: 架构模式是一个通用的.可重用的解决方案,用于在给定上下文中的软件体系结构中经常出现的问题.架构模式与软件设计模式类似,但具有更广泛的范围. 模型-视图-控制器模式,也称为MVC模式.是软件 ...

  8. 【windows 操作系统】【CPU】用户模式和内核模式(用户层和内核层)

    所有的现代操作系统中,CPU是在两种不同的模式下运行的: 注意以下内容来自微软: windows用户模式和内核模式 运行 Windows 的计算机中的处理器有两个不同模式:用户模式 和内核模式 . 用 ...

  9. 一个项目中说系统分为表现层、控制层、逻辑层、DAO层和最终数据库五层架构-转

    表现层就是看到的东西,比如你现在看到的当前页面控制层就将你的请求从页面传到后台代码逻辑层就是处理你的请求的代码DAO层就是将数据存到数据库中的代码数据库就是数据库了,存东西用的 ,DAO层就是将访问数 ...

随机推荐

  1. HTML中元素的定位方式

    初中物理就学过,位置是相对的,要有参照物,因此,所有定位都是相对参照物的定位. position 属性: 规定元素的定位类型,该属性的可选值有static.relative.absolute.fixe ...

  2. CSS3利用背景渐变和background-size配合完成渐变与条纹效果[持续更新中...]

    1.不等垂直条纹. <!-- 不等垂直条纹 --> <div class="div1"></div>div1 div{ width: 200px ...

  3. ubantu18.04下Hadoop安装与伪分布式配置

    1  下载 下载地址:http://mirror.bit.edu.cn/apache/hadoop/common/stable2/ 2 解压 将文件解压到 /usr/local/hadoop cd ~ ...

  4. [ 转载 ] Python Web 框架:Django、Flask 与 Tornado 的性能对比

    本文的数据涉及到我面试时遇到过的问题,大概一次 http 请求到收到响应需要多少时间.这个问题在实际工作中与框架有比较大的关系,因此特别就框架的性能做了一次分析. 这里使用 2016 年 6 月 9 ...

  5. BZOJ1712 : [Usaco2007 China]Summing Sums 加密

    设$s[i]$为进行$i$次加密后所有奶牛数字的和,有$s[i]=(n-1)s[i-1]$. 设$c[i]$为某头固定的奶牛进行$i$次加密后的数字, 若$i$为奇数,有: \[c[i]=((1-n) ...

  6. lvs+keepalived 02

    LVS keepalived 高可用负载均衡 环境 IP HOSTNAME Describe 192.168.100.30 lvs01 主负载 192.168.100.31 lvs02 备负载 192 ...

  7. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

  8. hdu 5726 GCD 暴力倍增rmq

    GCD/center> 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5726 Description Give you a sequence ...

  9. CentOS 7下的KVM网卡配置为千兆网卡

    在KVM下可以生成两种型号的网卡,RTL8139和E1000,其实应该是底层生成不同芯片的网卡,而不是附带宿主机网卡是什么型号就是什么型号的,其中默认为100兆网卡,即RTL8319的螃蟹卡,另一种是 ...

  10. C#Winform将WebBowser控件替换为Chrome内核

    摘要 由于最近要做一个浏览器式的软件,其中有不少地方需要使用到jQuery和BootStrap,但是在C#中,默认的WebBrowser控件默认使用的是IE的core,而低版本的IE在JS加载上总是容 ...