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.
This bit of information reveals lack of aggregate root - I would call it InstrumentClass
.
Introducing that into Your model would solve some of Your issues. InstrumentClass
would hold available instructors that teaches particular instrument.
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{
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…