Вот как бы я начал рисовать ...
У вас есть объект Course, который принимает объект Requirements и объект OnCompleteActions в его конструкторе ... если бы я сделал внутренний конструктор и создал бы CourseBuilder, который будет знать, как создавать все различные курсы, но ...
Когда курс обновляется, он проверяет, выполнены ли требования, передавая себя объекту требований. Если он удовлетворяет требованиям, он передается в OnCompleteActions.
private void OnCourseUpdate()
{
if (this._Requirements.AreMetBy(this))
{
this._OnCompleteActions.Execute(this);
}
}
Объект Requiremetns - это не что иное, как совокупный список IRequirement, который вы можете настроить на основе создаваемого вами курса ... Метод AreMetBy просто перечисляет все ваши IRequirements в списке и проверяет, удовлетворяет ли ваш курс всем им. ...
interface IRequirement
{
public bool IsMetBy(Course course);
}
Тогда у вас могут быть всевозможные требования, которые реализуют IRequirement ...
class CourseHoursRequirement : IRequirement
{
public CourseHoursRequirement(int minimumHours)
{...}
public bool IsMetBy(Course course)
{
return course.NumberHours >= this._MInimumHours
}
}
Та же идея для OnCompleteActions будет иметь список из одного или нескольких IOnCompleteAction, которые будут выполнять каждое из них. ех. CreateCertificateOnCompleteAction, SendEmailOnCompleteAction и т. Д.
Инкапсулируя каждое возможное Требование в своем собственном классе, вы можете затем создать курс, который будет иметь MinimumHourRequirement, PassedAllTestRequirement и т. Д. Вы можете легко добавлять новые требования по мере продвижения, поскольку все они реализуют один и тот же интерфейс. Возможно, вам придется добавить некоторые предельные свойства по мере использования (например, минимальные часы), но реальная работа выполняется внутри метода IsMetBy () ...
Удачи!