访问数据进行验证并使用DDD确定默认值 [英] Accessing data for validation and determining default values using DDD

查看:54
本文介绍了访问数据进行验证并使用DDD确定默认值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设一个项目,例如音乐学校的学生注册系统。

Lets take a hypothetical project such as a student enrollment system for a music school.


  • 在系统中,需要存在一种为有兴趣在这所学校接受教学的新学生输入学生数据的方法,我们可以假设学生可以通过网站访问此功能。

  • 注册过程的一部分询问学生她希望接收其指导的乐器类型。

  • 由于输入了有关她偏爱的乐器的信息,因此行为将是指派一名默认的讲师,该讲师被分配给该组乐器。

  • 在完成注册请求之前,学生还将能够将分配的教员更改为另外的教员,该教员也被列为能够为她选择的乐器提供教具。

  • Within the system there needs to exist a way to enter student data for a new student interested in receiving instruction at this school and we can assume that students may have access to this functionality through a web site.
  • Part of the enrollment process asks the student the type of instrument for which she would like to receive instruction.
  • As a result of entering information about her preferred musical instrument the behavior will be to assign a default instructor who is assigned to that group of instruments.
  • Before completing the enrollment request the student will be also be able to change the assigned instructor to different instructor who also is listed as able to give instructed for her selected instrument.

鉴于此说明,我遇到一点麻烦的部分是如何在有能力授课的教师中管理可能的教师列表对于特定的工具,首先要为新学生选择一名默认的讲师,其次是在提交入学之前验证所选的讲师时如何使用相同的数据。
其他技术限制是,到目前为止,我一直在使用一种自我验证技术,该技术与Jimmy Nilsson的书应用域驱动的设计和模式,因此,对于我来说,目前尚不清楚在访问时继续遵循自验证技术的最佳方法外部数据是必需的,我通常认为这些数据超出了测试有效性的实体范围。

Given this description, the part I'm having a little trouble with is how manage the list of possible instructors out of the ones who are able to give instruction for particular instrument in terms of choosing a default instructor for a new student first, and secondly how to use this same data when it comes time to validate the selected instructor before an enrollment is submitted. Other technical constraints are that up to this point I've been using a self validating technique very similar to the one presented in Jimmy Nilsson's book Applying Domain-Driven Design and Patterns so it is mainly unclear to me the best way to go about continuing following self validating techniques when access to external data is necessary which I would normally see as outside of the scope of the entity being tested for validity.

我知道的选项:


  1. 将验证移到实体本身之外。可能将验证移至每个实体的一组服务或单个服务中,该服务分析整个实体的当前状态并认为其有效或无效,并提供要发出的域事件或其他值对象,以提供有关验证规则的更多信息坏了。在这种情况下,我对服务如何访问有关讲师的必要信息仍然不满意

  2. 允许从尝试执行此操作的必要实体访问讲师存储库

  3. 创建一个服务,该服务允许按乐器类别访问教师列表。或者,创建两个单独的服务,一个返回给定类别的给定教师是否在给定类别的服务中,另一个返回给定类别的默认教员的服务。

  4. 加载列表我的汇总根(可能是学生或学生注册请求)中的指导者值对象,可以用于汇总根或根中包含的实体进行验证。

  1. Move validation outside of the entity itself. Perhaps validation is moved into a set of services or a single service per entity which analyses current state of the whole entity and deems it valid or not and provides for domain events or other value objects to be emitted that give more insight about what validation rules have been broken. In this case I'm still a bit uneasy about how the service would get access to the necessary information about instructors
  2. Allow for access to a instructor repository from necessary entities that are attempting to perform this validation.
  3. Create a service that allows access to a list of instructors by instrument category. Alternatively create two separate services, one that returns whether a given instructor is in the list of instructors for a given category, and another which returns the default instructor for a given category.
  4. Load a list of instructor value objects within my aggregate root (likely student, or a student enrollment request) that can be used for validation either by the aggregate root or entities contained within the root.

在上面的前两种情况中,似乎都没有必要使用教员存储库,因为我不需要访问代表教官的聚合根,但是在我的情况下,会将讲师视为描述学生入学请求的值对象,而让存储库吐回值对象似乎模糊了存储库应该做的事情。对于最后两个选项,在选项4的情况下,两个似乎允许从服务或工厂访问数据是错误的,因为不是应该由存储库来负责这种数据访问吗?并且,如果存储库是此逻辑的正确位置,那么在哪里可以访问或存储对存储库的引用?我一直坚信,有理由不直接在构成模型的任何实体或价值对象中访问存储库,所以我想知道是否是在这种情况下我可能不得不屈从于这种假设。我还应该提到,我对DDD还是很陌生,而我刚遇到一些挠头的时刻,并试图不让自己陷入困境,因此,任何有关此主题的知识渊博的意见都将是有价值的。

In either of the first two cases above it seems like the use of a instructor repository would be overkill because I don't need to access an aggregate root that represents an instructor but instead in my case I would see the instructor as a value object that describes the student enrollment request and having a repository spit back value objects seems to be blurring the lines of what a repository is supposed to be doing. For the last two options it seems wrong two allow access to data from a service or a factory in the case of option 4 since aren't repositories supposed to be in charge of data access such as this? And if repositories are the right place for this logic where are the appropriate places to access or store references to repositories? I've been convinced that there are reasons not to access repositories directly within any entity or value object that makes up the model so I'm wondering if this is a case where I may have to bend on that assumption. I should also mention that I'm pretty new to DDD and I'm just now encountering some of my head scratching moments and attempting not to box myself in so any knowledgeable input on this topic would be valuable.

推荐答案


将验证移到实体本身之外。

Move validation outside of the entity itself.

一位教练不应该知道所有其他老师。对一组教员进行验证不是某个特定教员的责任。

One instructor shouldn't know about all other instructors. Validation against set of instructors isn't responsibility of one particular instructor.


允许试图从必要实体访问教员存储库的人员

Allow for access to a instructor repository from necessary entities that are attempting to perform this validation.

域模型应该对持久性不了解。需要中断以表明您的模型存在缺陷。

Domain model should be persistence ignorant. Need to break that indicates flaws in Your model.


创建一个服务,该服务允许按仪器类别访问教师列表。

Create a service that allows access to a list of instructors by instrument category.

此信息表明缺少聚合根-我将其称为 InstrumentClass

This bit of information reveals lack of aggregate root - I would call it InstrumentClass.

将其引入您的模型将解决您的一些问题。 InstrumentClass 将容纳可用的讲授特定乐器的讲师。

Introducing that into Your model would solve some of Your issues. InstrumentClass would hold available instructors that teaches particular instrument.

接下来的一件事,您需要弄清楚如何正确描述分配给班级的学生。不幸的是,我目前无法命名(也许是参与?)。但是该实体将用于 InstrumentClass 来确定哪些教师太忙。

Next thing You need to figure out is how to describe properly student that is assigned to class. Unfortunately I can't name it at the moment (maybe Participation?). But that entity would be used for InstrumentClass to figure out which instructors are too busy.

在建模您的域时,这是我的自由样式(仅显示我所看到的内容):

Here's my "free-style" (just to show what I see) on modeling Your domain:

using System;

public class Main{
  public Main(){
    var instructor = new Instructor();
    var instrument = new Instrument("saxaphone");
    var saxaphoneClass = new InstrumentClass(saxaphone,teacher);
    var me=new Person("Arnis");
    //here, from UI, I can see available classes, choose one
    //and choose according instructor who's assigned to it
    var request=me.RequestEnrollment(saxaphoneClass, instructor);
    saxaphoneClass.EnrollStudent(request);
  }
}
public class Person{
  public IList<EnrollmentRequest> EnrollmentRequests { get; private set; }
  public EnrollmentRequest RequestEnrollment
   (InstrumentClass instrumentClass,Instructor instructor){
    if (!instrumentClass.IsTeachedByInstructor(instructor))
      throw new Exception("Instructor does not teach this music instrument");
    var request=new EnrollmentRequest(this,instrumentClass,instructor);
    EnrollmentRequests.Add(request);
    return request;
  }
}
public class EnrollmentRequest{
  public Person Person{ get; private set; }
  public InstrumentClass InstrumentClass { get; private set; }
  public Instructor Instructor{ get; private set; }
}
public class InstrumentClass{
  public void EnrollStudent(EnrollmentRequest request){
    var instructor=request.Instructor;
    var student=new Student(request.Person);
    var studies=new Studies(this,student,instructor);
    //TODO: this directiveness isn't good
    //student/instructor should listen for class events themselves
    //and class should listen if by any reason instructor or student cannot
    //participate in studies
    student.EnrollInClass(studies);
    instructor.AssignStudent(studies);
    Studies.Add(studies);
  }
  public bool IsTeachedByInstructor(Instructor instructor){
    return Instructors.Contains(instructor);
  }
  public InstrumentClass
   (Instrument instrument, params Instructor[] instructors){
    Instrument=instrument; Instructors=instructors.ToList();
  }
  public IList<Instructor> Instructors{get;private set;}
  public IList<Studies> Studies { get; private set; }
  public Instrument Instrument { get; private set; }
}
public class Studies{
  public Student Student { get; private set; }
  public Instructor Instructor { get; private set; }
  public InstrumentClass InstrumentClass { get; private set; }
}
public class Student{
}
public class Instructor{
}
public class Instrument{
}

这篇关于访问数据进行验证并使用DDD确定默认值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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