我正绞尽脑汁试图正确地建模我的领域(指问题空间)。
这是一个包含28天的膳食计划。用户注册后,他们会被重定向到Onboard以回答一些问题(另存为mealplanresources vo),然后他们可以为28天中的每一天选择膳食(从我们的内部配方数据库)(如上图所示)。
这些是一些假定与day实体交互的用户用例。
用户可以添加/删除x天的膳食。
用户可以重置一天(删除所有膳食)。
用户可以将一天标记为完整/不完整(以防用户尚未烹调所有膳食)。
这是迄今为止我对域建模的方式(文件夹结构):
梅尔普兰(ar)
namespace App\MealPlan\Domain\Model;
use App\MealPlan\Domain\Model\Calendar\Calendar;
use App\MealPlan\Domain\Model\Calendar\CalendarId;
use App\MealPlan\Domain\Model\Calendar\Day\Days;
use Shared\Domain\Users\UserId;
final class MealPlan {
public function __construct(
private MealPlanId $id,
private UserId $userId,
private MealPlanResources $resources
){}
public static function create(
MealPlanId $id,
UserId $userId,
MealPlanResources $resources
): MealPlan {
return new self($id, $userId, $resources);
}
protected function createCalendar(
CalendarId $calendarId,
MealPlanId mealPlanId,
Days $days
): Calendar {
return new Calendar($calendarId, $mealPlanId, $days);
}
}
日历(实体)
namespace App\MealPlan\Domain\Model\Calendar;
use App\MealPlan\Domain\Model\MealPlanId;
use App\MealPlan\Domain\Model\Calendar\Day\{Day, Days, DayState};
final class Calendar {
public function __construct(
private CalendarId $id,
private MealPlanId $mealPlanId,
private Days $days
){}
public static function create(
CalendarId $id,
MealPlanId $mealPlanId,
Days $days
): Calendar {
return new self($id, $mealPlanId, $days);
}
public function days(): Days {
return $this->days;
}
public function resetDay(Day $day): void {
}
public function getDay(int $value): Day {
foreach($this->days->getIterator() as $day){
if($day->getDay() === $value){
return $day;
}
}
}
}
日(实体)
namespace App\MealPlan\Domain\Model\Calendar\Day;
class Day {
private MealCollection $meals;
public function __construct(
protected DayId $day,
protected CalendarId $calendarId,
protected DayState $state
){}
public function changeDayState(DayState $state): void {
// if day doesn't have 3 meals, state can't be set to DayState::COMPLETED
// throw error
$this->state = $state;
}
public function addMeal(Meal $meal): void {
// if meal already exists
// throw error
return $this->meals->add($meal);
}
public function removeMeal(): void {
// remove meal
}
public function getState(): DayState {
return $this->state;
}
}
基于以上,我认为应该在聚合根创建期间创建并持久化28天。但我不确定谁负责增加28天并坚持。是createcalendar方法中的mealplan,还是calendar factory方法本身中的mealplan?
1条答案
按热度按时间eblbsuwk1#
是createcalendar方法中的mealplan,还是calendar factory方法本身中的mealplan?
需要注意的是:当第一本ddd书籍出版时(evans,2003),领域实体是第五章中描述的一种模式,但生命周期管理模式(聚合、工厂、存储库)在第六章中进行了描述。
这里的部分想法是,您希望避免混合域代码和管道。是的,我们的模型需要在内存中表示日历、日期等,但企业并不特别关心在机器世界中如何实现这一点的细节。
换句话说,“正确地连接所有内容”与管理域模型中的信息如何变化无关。
因此,从“单一责任原则”可以看出,我们希望“将所有内容连接起来”的代码都隔离在具有该责任的单个模块中。
在其他条件相同的情况下,这可能意味着我们的第一个猜测应该是将尽可能多的“连接所有内容”代码放入工厂方法中,并让域实体专注于域。
当您从持久信息存储中加载聚合时,考虑您希望代码是什么样子可能会有所帮助。创建mealplan看起来很像从数据库加载mealplan——主要区别在于您从“其他地方”获取信息。