这并不能完全回答您的问题,但我认为域驱动设计的反面是数据库驱动设计。在数据库驱动设计中,首先创建数据库模式,然后在完全了解模式的情况下创建类。优点是您可以更好地了解“幕后”发生的事情,并将阻抗失配的影响降至最低。但是,缺点是数据库模式,因为它是关系型而不是面向对象的,不能很好地转换为对象(例如,关系型数据库中没有集合的概念)。
在域驱动设计中,理论上您可以像创建任何其他类一样创建数据对象,并将数据库视为简单的持久层。用 Layman 的话来说,数据库只是一个存储容器,你不关心对象是如何存储的,只关心它们以某种方式存储。这消除了阻抗不匹配,您不必担心一件事。然而,在实践中,您仍然需要了解对象的存储方式,并且当您使用的 ORM 尝试输出复杂的 SQL 查询时,可能会出现性能问题。
编辑:
这是一个原则上应该是什么样的领域驱动设计的示例。假设您有一个 Person 类,就像这样(在 C# 中):
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public ICollection<Person> Relatives { get; set; }
public Company Employer { get; set; }
}
现在,在关系数据库中,这可能会转换为 3 个表,即 Person 表、Address 表和 Company 表,它们之间有一堆关系。然而,这与程序员看待这个对象的方式大不相同。程序员将其视为具有 4 个参数的 Person 对象的实例,其中一个是 ICollection。这与数据库表结构不太匹配,因此是“阻抗不匹配”,或者用通俗的话来说,是关系模型和对象模型之间的布局差异。
在领域驱动设计中,我应该能够做到这一点:
Person person = new Person();
// set each property to something
Database.Save(person);
现在,person 对象被保存。我可以这样检索它:
Person databasePerson = Database.Get<Person>(idOfPerson);
它会返回我的Person 对象,就像我保存它之前一样。这样,我根本不关心数据库如何保存它,或者担心阻抗不匹配。我只是保存它并根据需要检索它。
不过,这都是理论上的。在实践中,您可能必须手动指定“映射”,或者类如何知道从数据库中的哪个表/列获取数据。当您尝试映射到更复杂的类型(例如字典和其他 ADT)以及尝试将多个表中的数据提取到一个类中时,它可能会变得非常复杂。