【发布时间】:2009-09-25 09:57:46
【问题描述】:
我刚刚读完 Eric Evans 的“领域驱动设计:解决软件核心的复杂性”,我正在尝试编写我的第一个以领域为中心的应用程序(使用 C#)。
我们的帮助台将使用该应用程序来跟踪计算机分配给用户的情况。
我画了一个简单的类图来反映领域的一部分。好像是这样的……
我还确定了我的第一个功能(将计算机分配给用户)并为它编写了一个测试...
[Test]
public void AllocateToUser()
{
var user = new Owner("user1");
var computer = new Computer("computer1");
computer.Allocate(user);
Assert.AreEqual(user.Username, computer.AllocatedTo.Username);
}
最后,我编写了代码以使测试通过。
public class Computer
{
public Computer(string name)
{
Name = name;
}
public string Name
{ get; private set; }
public Owner AllocatedTo
{ get; private set; }
public void Allocate(Owner owner)
{
AllocatedTo = owner;
}
}
public class Owner
{
public Owner(string username)
{
Username = username;
}
public string Username
{ get; private set; }
}
到目前为止,一切都很好(我认为)。
但是,显然这些都没有解决持久性问题。我想我需要为计算机引入一个存储库类。可能是这样的:
public class ComputerRepository
{
public void Store(Computer computer)
{
//Some persistence logic here (possibly using NHibernate?)
}
}
现在我卡住了。如何确保对计算机分配的用户所做的更改传递到存储库?
我似乎有以下选择:
修改 Computer 类的 Allocate 方法的实现,以实例化 ComputerRepositry 的实例并调用 Store 方法。
创建接口 IComputerRepository;修改 Computer 的构造函数以要求提供实现 IComputerRepository 的类的实例。在 Allocate 方法中,针对这个注入的实例调用 Store。
创建一个服务 (AllocationService),它将结束对 Allocate 和 Store 的调用。
-
将责任传递给客户端,对调用代码强制执行两个步骤:
- 在 Computer 类的实例上调用 Allocate
- 实例化 ComputerRepository 的一个实例并调用 Store。
这些似乎都不令人满意:
很难测试,因为我将直接在 Computer 类中实例化存储库。
通过使用依赖注入避免了这个问题。但是它仍然很难看,因为每次我想实例化 Computer 时都需要传入一些 IComputerRepository 实例。
过于程序化,未能将行为封装在域实体类中。
只是看起来很丑。
我该怎么办?
【问题讨论】:
标签: c# tdd domain-driven-design repository-pattern