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

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. 【LOJ】#2569. 「APIO2016」最大差分

    题解 第一个子任务直接询问最大最小,每次可以问出来两个,再最大最小-1再问两个,最多问\(\frac{N + 1}{2}\)次就还原出了序列 第二个子任务由于差分肯定会大于等于\(\lceil \fr ...

  2. 【Java】 大话数据结构(5) 线性表之双向链表

    本文根据<大话数据结构>一书,实现了Java版的双向链表. 在每个数据结点中都有两个指针,分别指向直接后继和直接前驱,这样的链表称为双向链表. 双向链表的结构如图所示: 查找元素可以根据元 ...

  3. Python3 贝叶斯分类

    # -*- coding: utf-8 -*- """ Created on Tue Jan 16 20:11:07 2018 @author: markli " ...

  4. Eclipse常见设置与操作

    Eclipse虽然被IDEA超越了,但仍然是最佳的JAVA开发工具哈.因为经常会在不同的开发环境中进行开发,所以对Eclipse常见操作做一个记录,以便于查阅,这部分内容会持续进行更新. 界面布局设置 ...

  5. AngularJS之jeDate日期控件基本使用

    业务背景: 初学AngularJs,最近一段时间,因业务需求,要求日期选择带有快捷键.时分秒等.鉴于AngularJS组件库ui-bootstrap没有此功能,找了一款基于原生JS实现的插件-jeDa ...

  6. C# asp.net 抓取需要登录的网页内容 抓取asp.net登录验证的网站

    private void btnASPNET_Click(object sender, EventArgs e)        {            Dictionary<string, s ...

  7. python3.5 自带的虚拟环境使用

    首先我们要选择一个目录作为虚拟环境的目录, 这里选择c:\myenv cd myenv python -m venv . #在当前目录下创建虚拟环境 创建完成之后,myenv下会多出一些文件 进入sc ...

  8. 错误跳转js

    <script type="text/javascript"> var t = 5; //倒计时的秒数 function showTime(){ document.ge ...

  9. android stuidio 导入项目问题。

    避免重新下载. === === === 改成自己对应的. ===== Gradle sync failed: Could not find method android() for arguments ...

  10. Sublime Text 2 快捷键(转)

    文件 File 新建文件 Ctrl + N 打开文件 Ctrl + O 打开最近关闭的文件 Ctrl + Shift + T 保存 Ctrl + S 另存为… Ctrl + Shift + S 关闭文 ...