架构模式逻辑层模式之:表模块(Table Model)

简介:

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

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"]; 
    } 
}


本文转自最课程陆敏技博客园博客,原文链接:http://www.cnblogs.com/luminji/p/3703836.html,如需转载请自行联系原作者

相关文章
|
11天前
|
JSON 监控 安全
探索微服务架构中的API网关模式
【9月更文挑战第22天】在微服务架构的海洋中,API网关如同一位智慧的守门人,不仅管理着服务的进出,还维护着整个系统的秩序。本文将带你一探究竟,看看这位守门人是如何工作的,以及它为何成为现代云原生应用不可或缺的一部分。从流量控制到安全防护,再到服务聚合,我们将一起解锁API网关的秘密。
|
2月前
|
分布式计算 负载均衡 API
微服务架构设计原则与模式
【8月更文第29天】随着云计算和分布式计算的发展,微服务架构已成为构建大型复杂应用的一种流行方式。这种架构模式将单个应用程序分解成一组小型、独立的服务,每个服务运行在其自己的进程中,并通过轻量级机制(通常是HTTP资源API)进行通信。本文将探讨微服务架构的基本设计原则、常用模式以及如何有效地划分服务边界。
147 3
|
2月前
|
弹性计算 Kubernetes Serverless
Kubernetes 的架构问题之Serverless Container中不支持特权模式的问题如何解决
Kubernetes 的架构问题之Serverless Container中不支持特权模式的问题如何解决
70 6
|
2月前
|
设计模式 监控 API
探索微服务架构中的API网关模式
在微服务的宇宙里,API网关是连接星辰的桥梁。它不仅管理着服务间的通信流量,还肩负着保护、增强和监控微服务集群的重任。本文将带你走进API网关的世界,了解其如何成为微服务架构中不可或缺的一环,以及它在实际应用中扮演的角色和面临的挑战。
|
2月前
|
C# 微服务 Windows
模块化革命:揭秘WPF与微服务架构的完美融合——从单一职责原则到事件聚合器模式,构建高度解耦与可扩展的应用程序
【8月更文挑战第31天】本文探讨了如何在Windows Presentation Foundation(WPF)应用中借鉴微服务架构思想,实现模块化设计。通过将WPF应用分解为独立的功能模块,并利用事件聚合器实现模块间解耦通信,可以有效提升开发效率和系统可维护性。文中还提供了具体示例代码,展示了如何使用事件聚合器进行模块间通信,以及如何利用依赖注入进一步提高模块解耦程度。此方法不仅有助于简化复杂度,还能使应用更加灵活易扩展。
61 0
|
2月前
|
前端开发 开发者 C#
WPF开发者必读:MVVM模式实战,轻松实现现代桌面应用架构,让你的代码更上一层楼!
【8月更文挑战第31天】在WPF应用程序开发中,MVVM(Model-View-ViewModel)模式通过分离应用程序的逻辑和界面,提高了代码的可维护性和可扩展性。本文介绍了MVVM模式的三个核心组件:Model(数据模型)、View(用户界面)和ViewModel(处理数据绑定和逻辑),并通过示例代码展示了如何在WPF项目中实现MVVM模式。通过这种方式,开发者可以构建更加高效和可扩展的桌面应用程序。
57 0
|
2月前
|
设计模式 测试技术 数据处理
|
2月前
|
负载均衡 监控 JavaScript
探索微服务架构下的API网关模式
【8月更文挑战第31天】在微服务的大潮中,API网关不仅是流量的守门人,更是服务间通信的桥梁。本文将带你深入理解API网关的核心概念、设计要点及其在微服务架构中的重要作用,同时通过代码示例揭示如何利用API网关提升系统的灵活性与扩展性。
|
2月前
|
负载均衡 监控 API
探索微服务架构中的API网关模式
在微服务架构的海洋中,API网关扮演着枢纽的角色。它不仅是客户端请求的接收者,也是各个微服务间通信的协调者。本文将深入探讨API网关的设计原则、实现策略以及它在微服务生态中的重要性。我们将通过实际案例分析,了解API网关如何优化系统性能、提高安全性和简化客户端与服务的交互。
43 4
|
2月前
|
消息中间件 前端开发 编译器
10种常见的软件架构模式简述
10种常见的软件架构模式简述
下一篇
无影云桌面