65.9K
CodeProject 正在变化。 阅读更多。
Home

Fowler 的企业应用程序模式中的域逻辑示例

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (4投票s)

2009年1月21日

CPOL

3分钟阅读

viewsIcon

35106

downloadIcon

154

一个用 C# 实现 Fowler 的事务脚本模式的项目。

引言

我最近开始阅读 Martin Fowler 的《企业应用架构模式》。 我对他在事务脚本模式的描述感到困惑,所以我创建了一个 Visual Studio 解决方案,实现了他在该章节中使用的示例。 Fowler 没有在他的网站上提供代码示例/解决方案,而且我找不到其他人也在 CodeProject 上做了类似的项目,所以我从头开始。 随附的 Zip 文件包括一个数据库脚本和一个 VS2008 解决方案,以帮助任何正在阅读相同文本的人。

背景

此代码旨在配合 Fowler 的《企业应用程序架构模式》(第 14 版印刷版),第 110-115 页。

Using the Code

随附的 Zip 文件包括几个文件: 应运行 DomainLogicPatternsDatabase.sql 来设置数据库。 您需要配置 App.config 以连接到数据库。

FowlerTransactionScript 解决方案包含两个项目(DomainLogic 项目和一个控制台项目)。 领域逻辑基于 Fowler 在项目中用于演示业务层构建的 Java 代码。 我添加了接口以使事情更容易理解。 控制台项目代表 UI 层。

有几点需要注意

  1. UI 层引用 System.Data,因为 DataTable 是用于跨层保存数据的数据结构。 这与 Table Module 模式非常接近。 也许,他应该使用一个通用的数据结构来真正展示区别?
  2. 业务逻辑在 ReconignitionService.CalculateRevenueRecognitions 函数中实现。
datatable = gateway.FindContract(contractId);
decimal totalRevenue = Decimal.Parse(datatable.Rows[0][1].ToString());
DateTime recognitionDate = DateTime.Parse(datatable.Rows[0][2].ToString());
string contractType = datatable.Rows[0][5].ToString();
decimal revenuePiece = 0;

switch (contractType)
{
    case "S":
        revenuePiece = totalRevenue / 3;
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate);
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate.AddDays(60));
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate.AddDays(90));
        break;

    case "W":
        gateway.InsertRecognition(contractId, totalRevenue, recognitionDate);
        break;

    case "D":
        revenuePiece = totalRevenue / 3;
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate);
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate.AddDays(30));
        gateway.InsertRecognition(contractId, revenuePiece, recognitionDate.AddDays(60));
        break;

    default:
        break;
}

如果此代码被 TSQL 替换并放置在数据库中,则 ReconignitionService.CalculateRevenueRecognitions 将只调用一个存储过程。 我想知道这是否仍然是事务脚本模式? 一方面,接口没有改变。 但另一方面,领域逻辑是直接位于数据层。

领域逻辑

随附的 Zip 文件包括两个项目 - 领域逻辑层项目和用户界面(控制台)项目。 我没有将数据库连接到此项目。 如果你想看看如何做到这一点,请使用这里找到的项目。

领域逻辑中的关键类是 Product 和 Contract。 不幸的是,Fowler 的代码片段不正确,而且他没有提供完整的解决方案,所以我不得不拼凑一些东西来实现他的意图。 在这个例子中,您创建一个产品,然后将该产品与一个(或多个)合同关联,然后通过产品计算识别。 这对我来说似乎是违反直觉的 - 我会认为合同应该负责计算它们自己的识别,但这不是他设置的方式。

我与这本书的另一个不同之处在于识别策略。 他使用了一个抽象类,我使用了一个接口。 两者都会让你到达同一个地方,但一般来说,接口 > 抽象类,胜者是跑者。

关注点

无。

历史

  • 版本 1.0 - 2009 年 1 月 21 日。
  • 版本 2.0 - 2009 年 2 月 3 日
    • 添加了领域逻辑部分
© . All rights reserved.