具有行为和 ORM 的丰富领域模型 [英] Rich domain model with behaviours and ORM

查看:25
本文介绍了具有行为和 ORM 的丰富领域模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在观看 Jimmy Bogard 的 NDC12 演示制作邪恶的领域模型"后 (http://ndcoslo.oktaset.com/议程),我在徘徊如何坚持这种领域模型.
这是演示文稿中的示例类:

After watching NDC12 presentation "Crafting Wicked Domain Models" from Jimmy Bogard (http://ndcoslo.oktaset.com/Agenda), I was wandering how to persist that kind of domain model.
This is sample class from presentation:

public class Member
{
    List<Offer> _offers;

    public Member(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
        _offers = new List<Offer>();
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public IEnumerable<Offer> AssignedOffers { 
        get { return _offers; }
    }

    public int NumberOfOffers { get; private set; }

    public Offer AssignOffer(OfferType offerType, IOfferValueCalc valueCalc)
    {
        var value = valueCalc.CalculateValue(this, offerType);
        var expiration = offerType.CalculateExpiration();
        var offer = new Offer(this, offerType, expiration, value);
        _offers.Add(offer);
        NumberOfOffers++;
        return offer;
    }
}

所以这个领域模型中包含了一些规则:
- 会员必须有名字和姓氏
- 优惠数量不能在外面更改
- 会员负责创建新优惠,计算其价值和分配

so there are some rules contained in this domain model:
- Member must have first and last name
- Number of offers can't be changed outside
- Member is responsible for creating new offer, calculating its value and assignment

如果尝试将其映射到诸如实体框架或 NHibernate 之类的 ORM,它将不起作用.那么,使用 ORM 将这种模型映射到数据库的最佳方法是什么?
例如,如果没有 setter,我如何从 DB 加载 AssignedOffers?

If if try to map this to some ORM like Entity Framework or NHibernate, it will not work. So, what's best approach for mapping this kind of model to database with ORM?
For example, how do I load AssignedOffers from DB if there's no setter?

唯一对我有意义的是使用命令/查询架构:作为结果,查询总是使用 DTO 来完成,而不是域实体,并且命令是在域模型上完成的.此外,事件溯源非常适合领域模型上的行为.但是这种 CQS 架构可能并不适合每个项目,尤其是棕地.还是不行?

Only thing that does make sense for me is using command/query architecture: queries are always done with DTO as result, not domain entities, and commands are done on domain models. Also, event sourcing is perfect fit for behaviours on domain model. But this kind of CQS architecture isn't maybe suitable for every project, specially brownfield. Or not?

我知道这里有类似的问题,但找不到具体的例子和解决方案.

I'm aware of similar questions here, but couldn't find concrete example and solution.

推荐答案

这实际上是一个很好的问题,也是我考虑过的问题.创建完全封装的适当域对象(即没有属性设置器)并使用 ORM 直接构建域对象可能很困难.

This is actually a very good question and something I have contemplated. It is potentially difficult to create proper domain objects that are fully encapsulated (i.e. no property setters) and use an ORM to build the domain objects directly.

根据我的经验,有 3 种方法可以解决此问题:

In my experience there are 3 ways of solving this issue:

  • 正如 Luka 已经提到的,NHibernate 支持映射到私有字段,而不是属性设置器.
  • 如果使用 EF(我认为它不支持上述),您可以使用 备忘录模式 来恢复状态到您的域对象.例如您使用实体框架来填充域实体接受的备忘录"对象以设置其私有字段.
  • 正如您所指出的,将 CQRS 与事件溯源结合使用可以消除这个问题.这是我制作完美封装的域对象的首选方法,它还具有事件溯源的所有附加优势.
  • As already mention by Luka, NHibernate supports mapping to private fields, rather than property setters.
  • If using EF (which I don't think supports the above) you could use the memento pattern to restore state to your domain objects. e.g. you use entity framework to populate 'memento' objects which your domain entities accept to set their private fields.
  • As you have pointed out, using CQRS with event sourcing eliminates this problem. This is my preferred method of crafting perfectly encapsulated domain objects, that also have all the added benefits of event sourcing.

这篇关于具有行为和 ORM 的丰富领域模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆