如何在DDD上使用继承 [英] How to work with inheritance on DDD

查看:342
本文介绍了如何在DDD上使用继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试DDD并阅读Evans的书。我已经得出了一个模型,该模型的根是学生。现在,我需要(或能够区分)一个RegisteredStudent和一个EnrolledStudent(继承自RegisteredStudent)。我不知道如何处理DDD中的继承。

I am currently trying out DDD and reading Evans book. I have arrived at a model that has an aggregate whose root is Student. Now I need to have (or be able to distinguish) a RegisteredStudent and an EnrolledStudent (inherits RegisteredStudent). I don't know how to handle inheritance in DDD.


  1. 2个继承的类是否应该在聚合中?如果是这样,它们是否也被视为聚合根,因为它们的身份与根相同(仅向它们添加了属性)?如果没有,我该如何授予其他实体的访问权限?

  1. Should the 2 inherited classes be inside the aggregate? If so, are they also considered aggregate roots since their identity is the same as the root (there are only added properties to them)? If not, how do I give access to them from other entities?

还是不应该使用继承?为什么?

Or should I not be using inheritance? Why?

还有,如果集合中的实体不是根实体,但又需要它在外部继承实体,该怎么办?您应该如何处理?

And also, what if you have an entity in an aggregate that isn't a root, but you need it to inherit an entity outside? How should you go about it?


推荐答案

您需要问自己的问题这是RegisteredStudent和EnrolledStudent是否是不同的概念。

What you need to ask yourself here is whether a RegisteredStudent and an EnrolledStudent are different concepts. Are they not both students, but just in a different state?

总的来说,您应该更喜欢组合而不是继承。

In general, you should favor composition over inheritance.

这是我会做的一个例子。 (请注意,这只是我的示例,我不知道域,所以它不是一个确定的解决方案。)

Here's an example of what I would do. (Note that it's just my example, I don't know the domain, so it's not a definitive solution).

您可以有一个Student类,这是您的总计root和几个不同的状态类:已注册已注册。这样一来,您无需在Student上公开这些状态类,而只需在Student上公开方法。一个小例子(在c#中):

You could have a Student class, which is your aggregate root and then a few different state classes: Registered and Enrolled. That way you don't need to expose these state classes on the student but you could just expose methods on the Student. A small example (in c#):

class Student
{
    State _currentState;
    void Enroll()
    {
        if(!_currentState is Registered)
            throw new InvalidOperationException("Cannot enroll student who is not registered");

        this._currentState = new Enrolled();
    }

    void Register(string name)
    {
        this._currentState = new Registered(name);
    }
}

class StudentState{}

class Enrolled : StudentState
{}

class Registered : StudentState
{
    public Registered(string name)
    {
        Name = name;
    }
    public string Name {get; private set;}
}

这是State-design模式的简单应用,您可以将它的更多部分外部化并构建完整的状态机,但我将由您自己决定。 (而且它是直接输入到SO编辑器中的,因此可能会出现语法错误)

This is a simple application of the State-design pattern, you could externalize more parts of it and build a complete state-machine, but I'll leave that up to you. (Also it's typed directly in to the SO-editor, so there could be syntax errors)

在评论后进行编辑:

是否需要公开状态属性取决于上下文。通常,我建议不要这样做,因为您要公开学生的内部构造。例如,最好公开一个名为 CanEnroll 的方法。这样,您就可以更改状态模式的内部实现,而不会影响任何客户端。

Whether you need to expose a State-property or not depends on the context. In general I would recommend not to do that, because you're exposing the internals of the Student. It would be better to expose a method called CanEnroll for example. That way you can change the internal implementation of your state pattern without affecting any clients.

对于问题3,没有用例就很难说。但是,这里有一些指导原则:

As for question 3, it's hard to say without a use case. However, here are some guidelines:


  • 继承时最喜欢的构成(再次,我知道)

  • 您可以从集合体内部获得对外部世界的引用,但是您不应该反过来进行引用。

这篇关于如何在DDD上使用继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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