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





3.00/5 (4投票s)
一个用 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 层。
有几点需要注意
- UI 层引用
System.Data
,因为DataTable
是用于跨层保存数据的数据结构。 这与 Table Module 模式非常接近。 也许,他应该使用一个通用的数据结构来真正展示区别? - 业务逻辑在
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 日
- 添加了领域逻辑部分