Skip to content

工厂

工厂是不是设计模式里的“工厂”模式?

不完全是。DDD里的工厂,强调的是封装聚合从无到有的创建过程;面向对象编程里的工厂模式,是封装对象的实例化过程。DDD的工厂是特定于聚合说的,而工厂模式可以是任意对象。DDD的工厂,关注在业务上聚合的从无到有,而不是技术上的对象的实例化。因此仓储去载入聚合的时候,也会实例化聚合对应的对象,但是那个过程就不使用工厂,因为仓储载入聚合,在业务上聚合之前就已经存在了,只是没有载入内存而已。

工厂是领域服务吗?

是的。无状态的领域对象,封装一些领域逻辑,符合对领域服务的定义,因此它是一种领域服务。

每个聚合都要有工厂吗?

大部分聚合都要有个工厂。少数情况下,一些聚合一直存在,没有创建过程,就不需要有工行了。

实体和值对象也要有工厂吗?

不需要。工厂是封装聚合从无到有的过程,是针对聚合的。聚合内的对象,由这个聚合的聚合根负责创建,没必要在外面找一个领域服务去封装了。

工厂可以是抽象的,在领域模块外实现吗?

可以,比如聚合的实现类在领域模块之外,那只能通过领域模块外的工厂的实现类去调用聚合的实现类了,那工厂自然是抽象的。

工厂接受命令去创建聚合好,还是接受一些普通参数去创建聚合?

都可以。如何设计工厂的函数,取决哪个更容易读懂,更容易重用。

在工厂里发出“已创建”聚合的领域事件好,还是在聚合构造函数里发出好?

在工厂发出更好,避免在仓库载入聚合的时候,不小心调用错了构造函数,发出了创建聚合的领域事件。

工厂可以调用仓储吗?

当然可以。

工厂可以使用别的聚合吗?

当然可以。比如,创建一个聚合的过程中,需要使用别的聚合,那就载入别的聚合,使用起来啊。

在CommandHandler里面去做校验,还是在工厂里去做校验?

如果这个校验逻辑不是所有创建聚合的场景都要用,只是这个命令执行时用,那就放到这个命令的CommandHanadler里。如果只要创建这个聚合都要用,那就放到工厂里。