是否有丰富的领域模型示例?

hsvhsicv  于 2021-07-05  发布在  Java
关注(0)|答案(3)|浏览(368)

**结束。**此问题不符合堆栈溢出准则。它目前不接受答案。
**想改进这个问题吗?**更新问题,使其成为堆栈溢出的主题。

11个月前关门了。
改进这个问题
我正在寻找一个简单的例子来说明使用富域模型的好处。理想情况下,我想要一个前后代码列表(应该尽可能短)。
前代码清单应该显示使用贫乏的域模型和大量相当程序化的服务层代码解决的问题,后代码清单应该显示使用丰富的、面向对象的域模型解决的相同问题。
理想情况下,代码清单应该是java或groovy,但任何类似的代码(例如c#)都可以。

kkbh8khc

kkbh8khc1#

这并不能完全回答您的问题,但我认为域驱动设计与数据库驱动设计截然相反。在数据库驱动的设计中,首先创建数据库模式,然后创建完全了解该模式的类。这样做的好处是,您可以更好地了解“引擎盖下”发生了什么,并将阻抗失配的影响降到最低。然而,缺点是数据库模式,因为它是关系的而不是面向对象的,不能很好地转换为对象(例如,关系数据库中没有集合的概念)。
在域驱动的设计中,理论上,您可以像创建任何其他类一样创建数据对象,并将数据库简单地视为持久层。用外行的话说,数据库只是一个存储容器,你不关心对象是如何存储的,只关心它们是以某种方式存储的。这消除了阻抗失配,你有一件事少担心。然而,在实践中,您仍然必须知道对象是如何存储的,并且当您使用的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 对象,就像我保存它之前的样子。这样,我根本不关心数据库如何保存它,也不担心阻抗不匹配。我只是保存它,并根据需要检索它。
不过,这都是理论上的。实际上,您可能需要手动指定“Map”,或者类如何知道从数据库中的哪个表/列获取数据。当您试图Map到更复杂的类型(如字典和其他adt)时,以及当您试图将多个表中的数据拉入一个类时,它可能会变得相当复杂。

tmb3ates

tmb3ates2#

我认为没有人做过这样的比较,如果是这样的话,那就不小了。领域驱动设计试图解决复杂性,一个简单的例子并不包含复杂性。
也许领域驱动的设计一步一步地给你一些答案。

ny6fqffe

ny6fqffe3#

我将为您提供一个实际生产代码的简单示例:
person.groovy公司:

List addToGroup(Group group) {
    Membership.link(this, group)
    return groups()
  }

会员资格.groovy:

static Membership link(person, group) {
    def m = Membership.findByPersonAndGroup(person, group)
    if (!m) {
        m = new Membership()
        person?.addToMemberships(m)
        group?.addToMemberships(m)
        m.save()
    }
    return m
}

每当我想将一个人绑定到一个组时,我可以只执行person.addtogroup(group)
程序代码如下,在控制器上:

def m = Membership.findByPersonAndGroup(person, group)
 if (!m) {
        m = new Membership()
        person?.addToMemberships(m)
        group?.addToMemberships(m)
        m.save()
}

乍一看,你可以说,你可以 Package 在一个函数,你很好去。但丰富的领域设计imho的优点是它更接近于你的思维方式,因此更接近于合理化。在这个特定的例子中,我只想将一个人添加到一个组中,代码将读取这个。
这是一个简短的例子,正如您所要求的,但是很容易扩展这个例子,并看到您可以通过适当的领域建模来构建复杂的交互。
您还可以查看martinfowler的transaction script vs domain model对这两种模式的简要说明,我认为这两种模式与ddd有关。

相关问题