DDD(领域驱动设计),如何处理实体状态的变化,封装业务规则,需要大量的数据进行proccessed [英] DDD (Domain Driven Design), how to handle entity state changes, and encapsulate business rules that requires large amount of data to be proccessed

查看:277
本文介绍了DDD(领域驱动设计),如何处理实体状态的变化,封装业务规则,需要大量的数据进行proccessed的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public class Person
{
    public IList<String> SpecialBirthPlaces;
    public static readonly DateTime ImportantDate;
    public String BirthPlace {get;set;}

    public DateTime BirthDate
    {
        set
        {
            if (BirthPlace!=null && 
                value < ImportantDate && 
                SpecialBirthPlaces.Contains(BirthPlace))
            {
                BirthPlace = DataBase.GetBirthPlaceFor(BirthPlace, value);
            }
        }
    }
}

这是封装在我的域模型的简单规则的一种尝试。我试图捕捉法则就是:当由于某种原因,我们更新一个人的出生日期(例如,有在原来的用户输入错误),我们需要检查这个人的出生地,并与来自其他值替换。数据库,如果我们作为一个特殊的发源地数据库中列出

This is an attempt to encapsulate a simple rule in my domain model. The rule I'm trying to capture is: when, for some reason, we update a person's birth date (e.g. there was a mistake in the original user input) we need to check the person's birthplace and replace it with some other value from a database, if it is listed in our database as a special birthplace.

不过,我有2个问题,实现它:

However, I have 2 problems implementing it:


  1. 本规则修改域实体状态(属性),我需要反映在用户界面这一变化。我的域模型是POCO。我可以把在视图模型这样的逻辑,但这是错误的,因为它不是UI逻辑。这是我需要捕获的重要领域的规则。

  1. This rule modifies domain entity state (property) and I need to reflect this change in the user interface. My domain model is POCO. I could put this logic in the ViewModel, but this is wrong because it's not UI logic. It's an important domain rule which I need to capture.

我SpecialBirthPlaces名单是相当大的,我不希望每次我得到一次填充它从客户数据库。另外,我需要一个替代出生地时,规则是满意的。正如我所说的特殊的发祥地和更换的名单,这是非常大的,并存储在数据库中。

My list of SpecialBirthPlaces is pretty big and I don't want to populate it every time I get a customer from database. Also, I need to get a replacement for Birthplace when the rule is satisfied. As I said the list of special birthplaces and replacements for this is very big and is stored in the DB.

如何实现我需要在DDD风格逻辑?

How to implement the logic I need in DDD style?

推荐答案

我认为声明我需要反映在用户界面这一变化和这是我需要捕捉描述两个不同的问题的重要领域的规则。清楚地,第一个需要解决;目前尚不清楚这第二个呢。

I think the statements "I need to reflect this change in the user interface" and "It's an important domain rule which I need to capture" describe two different problems. Clearly, the first one needs to be solved; it isn't clear that the second one does.

如果您的域模型的其他部分需要了解的变化在这里,你会做得很好有一个看看域事件(例如,乌迪大汉的实现) 。你也可以使用这个时候出生日期被设定,即使异步如果它是一个潜在的冗长的操作设置发源地属性。

If other parts of your domain model need to know about changes here, you would do well to have a look at Domain Events (for example, Udi Dahan's implementation). You could also use this to set the BirthPlace property when the BirthDate gets set, even asynchronously if it is a potentially lengthy operation.

否则,我们只是看看在用户界面问题。首先,在我的域模型,我将有抽象为一个接口的每个实体。如果不这样做,那么你可能需要至少做出一些特性虚拟。我还可以使用一个抽象层的生成/返回我的实体,如IOC /工厂/存储库。我认为这一层是域模型本身的范围之外。

Otherwise, let's just look at the UI issue. First of all, in my domain model, I would have each entity abstracted as an interface. If you don't, then you may need to at least make some properties virtual. I'd also be using a layer of abstraction for generation/returning my entities, such as IoC/factory/repository. I consider this layer to be outside the bounds of the domain model itself.

现在,我们需要一种机制来改变的UI通知域实体的属性,但当然,领域模型本身在某种意义上是一个封闭的系统。我们不希望引入新成员或行为,以满足任何外界关注的需求。

Now, we need a mechanism to notify the UI of changes to properties in domain entities, but of course the domain model itself is in a sense a closed system: we don't want to introduce new members or behaviours to satisfy the needs of any outside concern.

如果我们装修有关的实体实施实现 INotifyPropertyChanged的?我们可以在我们的资料库,我们已经建立是域的边界之外做到这一点,所以我们不会修改域模型本身,只用成分与域模型外,系统需要的功能来包装实体。要重申,发源地重新计算保持域模型的关注,而UI通知逻辑依然域模型的关注的 的外面。

What if we decorate the entity in question with an implementation that implements INotifyPropertyChanged? We could do this in our repository, which we've established is outside the bounds of the domain, so we would not be modifying the domain model itself, only using composition to wrap the entities with functionality that the system outside the domain model needs. To restate, the recalculation of BirthPlace remains a concern of the domain model, while the UI notification logic remains a concern outside of the domain model.

这将是这个样子:

public class NotifyPerson : IPerson, INotifyPropertyChanged
{
    readonly IPerson _inner;

    public NotifyPerson(IPerson inner) // repository puts the "true" domain entity here
    {
        _inner = inner;
    }

    public DateTime BirthDate
    {
        set 
        {
            if(value == _inner.BirthDate)
                return;

            var previousBirthPlace = BirthPlace;
            _inner.BirthDate = value;
            Notify("BirthDate");

            if(BirthPlace != previousBirthPlace) 
                Notify("BirthPlace");
        }
    }

    void Notify(string property)
    {
        var handler = PropertyChanged;
        if(handler != null) handler(this, new PropertyChangedEventArgs(property));
    }
}

如果不使用接口,只需将继承并重写出生日期属性,呼吁基地成员代替的 _inner

If not using interfaces, you would simply inherit from Person and override the BirthDate property, calling members on base instead of _inner.

这篇关于DDD(领域驱动设计),如何处理实体状态的变化,封装业务规则,需要大量的数据进行proccessed的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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