3

我经常在业务对象上看到这样的例子:

public void Save()
{
     if(this.id > 0)
     {
          ThingyRepository.UpdateThingy(this);
     }
     else
     {
          int id = 0;
          ThingyRepository.AddThingy(this, out id);
          this.id = id;
     }
}

那么为什么在这里,在业务对象上呢?这似乎与上下文或数据相关,而不是业务逻辑。

例如,这个对象的消费者可能会经历这样的事情......

...Get form values from a web app...

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
thingy.Save();

或者,类似这样的更新...

... Get form values from a web app...

Thingy thingy = Thingy.GetThingyByID(Int32.Parse(Form["id"].Value));
Thingy.Name = Form["name"].Value;
Thingy.Save();

那么这是为什么呢?为什么不包含实际的业务逻辑,例如计算、业务特定规则等,并避免检索/持久化?

使用这种方法,代码可能如下所示:

... Get form values from a web app...

Thingy thingy = Thingy.CreateNew(Form["name"].Value, Form["gadget"].Value, Form["process"].Value);
ThingyRepository.AddThingy(ref thingy, out id);

或者,类似这样的更新...

... get form values from a web app ...

Thingy thingy = ThingyRepository.GetThingyByID(Int32.Parse(Form["id"].Value));
thingy.Name = Form["Name"].Value;
ThingyRepository.UpdateThingy(ref thingy);

在这两个示例中,最了解对象正在做什么的消费者调用存储库并请求添加或更新。该对象在该上下文中仍然是 DUMB,但仍提供与其自身相关的核心业务逻辑,而不是如何检索或保留它。

简而言之,我没有看到在业务对象本身中整合 GET 和 SAVE 方法的好处。

我应该停止抱怨和顺从,还是我错过了什么?

4

4 回答 4

4

这导致了Active Record 模式(参见EAA 第 160 页的 P)。

我个人不是粉丝。紧密耦合业务对象和持久性机制,以便更改持久性机制需要更改业务对象?将数据层与域层混合?违反单一责任原则?如果我的业务对象是,Account那么我有实例方法Account.Save,但要找到一个帐户,我有静态方法Account.Find吗?好恶心。

也就是说,它有它的用途。对于具有直接符合数据库模式的对象并且具有简单的域逻辑并且不关心易于测试、重构、依赖注入、打开/关闭、关注点分离等的小型项目,它可能是一个不错的选择。

于 2009-07-29T13:59:09.790 回答
2

您的域对象不应引用持久性问题。

在域中创建一个代表持久服务的存储库接口,并在域外实现它(您可以在单独的程序集中实现它)。

这样,您的聚合根不需要引用存储库(因为它是聚合根,它应该已经拥有它需要的一切),并且它不会有任何依赖或持久性问题。因此更容易测试,并且专注于领域。

于 2009-07-29T13:36:08.017 回答
0

虽然我不了解 DDD,但有 1 种方法是有意义的(它将执行 UPSERT。如果记录不存在则插入,否则更新)。

该类的用户可以装傻并在现有记录上调用 Save 并在新记录上调用 Update。有一个行动点要清楚得多。

编辑:是否执行 INSERT 或 UPDATE 的决定最好留给存储库。用户可以调用 Repository.Save(....),这可能会导致新记录(如果记录不在数据库中)或更新。

于 2009-07-29T04:29:13.680 回答
0

如果您不喜欢他们的方法,请自行制作。个人对业务对象的 Save() 实例方法对我来说真的很好闻。我需要记住的班级名称少了一个。但是,我对工厂保存没有问题,但我不明白为什么两者都很难。IE

class myObject
{
   public Save()
   {
      myObjFactory.Save(this);
   }
}
...

class myObjectFactory
{
   public void Save(myObject obj)
   {
      // Upsert myObject   
   }
}
于 2009-07-29T04:45:13.413 回答