php—在单个事务中示例化相同实体的正确方法?

2skhul33  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(238)

我正绞尽脑汁试图正确地建模我的领域(指问题空间)。
这是一个包含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?

eblbsuwk

eblbsuwk1#

是createcalendar方法中的mealplan,还是calendar factory方法本身中的mealplan?
需要注意的是:当第一本ddd书籍出版时(evans,2003),领域实体是第五章中描述的一种模式,但生命周期管理模式(聚合、工厂、存储库)在第六章中进行了描述。
这里的部分想法是,您希望避免混合域代码和管道。是的,我们的模型需要在内存中表示日历、日期等,但企业并不特别关心在机器世界中如何实现这一点的细节。
换句话说,“正确地连接所有内容”与管理域模型中的信息如何变化无关。
因此,从“单一责任原则”可以看出,我们希望“将所有内容连接起来”的代码都隔离在具有该责任的单个模块中。
在其他条件相同的情况下,这可能意味着我们的第一个猜测应该是将尽可能多的“连接所有内容”代码放入工厂方法中,并让域实体专注于域。
当您从持久信息存储中加载聚合时,考虑您希望代码是什么样子可能会有所帮助。创建mealplan看起来很像从数据库加载mealplan——主要区别在于您从“其他地方”获取信息。

相关问题