java - DDD 聚合根,如何创建不同类型的新子聚合元素?工厂方法?

标签 java php oop domain-driven-design aggregateroot

<分区>

假设我们有作为聚合根的提升和满足作为聚合的提升的规则。 规则是扩展抽象类规则的不同规则元素的集合。

据我所知,我可以使用工厂方法,例如:

class Promotion (
    PromotionIdentity $identity,
    string $name,
){
    $this->identity = $identity;
    $this->name = $name;
    $this->rules = new RuleCollection();   
}

public function addRule(
    RuleIdentity $ruleIdentity,
    RuleType $ruleType,
    array $configuration
) {
    if (RuleType::EMAIL_LIST === $ruleType->value()) {
        $makeRule = new EmailListRule($ruleIdentity, $configuration);
        $this->rules->add($makeRule);
    }

    if (RuleType::MIN_ARTICLES === $ruleType->value()) {
        $makeRule = new MinimumArticlesRule($ruleIdentity, $configuration);
        $this->rules->add($makeRule);
    }

    ... and so on, for example 15 rules
}

我认为这可以增长很多,我在这里看到了代码味道。

将规则创建的逻辑保留在聚合根中可以吗?我们可以将规则创建的这种责任转移到工厂内的应用程序服务,并将构建的规则传递给 addRule 方法吗?其他选择?谢谢 friend 们!

最佳答案

Rules to satisfy a promotion as an Aggregate

好吧,一个 AR 不能包含其他 AR 的实例,所以 Rule 在这里可能不是一个 AR。此外,乍一看,在不知道您的域的情况下,我认为 Rule 几乎没有理由从域的角度来看甚至是一个实体(它可以从存储的角度来看)。 Rule 不能只是一个值对象,如果需要更改则完全替换吗?

//Application service
changePromotionRules(String promotionId, Set<Map<String, String>> rulesConfig) {
    Set<Rule> rules = ruleFactory.rulesFromConfig(rulesConfig);
    Promotion promotion = promotionRepository.promotionOfId(new PromotionIdentity(promotionId));
    promotion.changeRules(rules);
}

//Promotion AR
changeRules(Set<Rule> rules) {
    validateRules(rules);
    this.rules = rules;
}

上面的例子假设了一个类似 CRUD 的行为,其中所有的规则都被一次替换,但是你可以用更细粒度的 addRule/removeRule 操作来做同样的事情,这可能是更适合。

如果您在 UI 行为(例如一次保存所有规则)和域(例如 addRule/removeRule)之间存在脱节,那么您可以在应用程序服务层对此进行调整。

例如

//Application service
changePromotionRules(String promotionId, Set<Map<String, String>> rulesConfig) {
    Set<Rule> rules = ruleFactory.rulesFromConfig(rulesConfig);
    Promotion promotion = promotionRepository.promotionOfId(new PromotionIdentity(promotionId));
    withSetDiffBetween(rules, promotion.rules(), new SetDiffHandler<Rule>() {
         withAdd(Rule rule) { promotion.addRule(rule); }
         withRemove(Rule rule) { promotion.removeRule(rule); }
    });
}

关于java - DDD 聚合根,如何创建不同类型的新子聚合元素?工厂方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53848783/

相关文章:

C++ OOP 重复继承模式

java - 如何使用HttpClient将文件上传到Ubuntu的特定路径

php - "How the sausage is made"apache/php/mysql交互之旅

java - 将 ResultSet 添加到 Jtable 中(两个类之间)

php - 使用 PHP 对移动设备进行 token 身份验证

PHP数组到json可读输出

python - 修复 "IFs hell"的最佳方法是什么?

java - 什么时候应该使用工厂方法模式? (而不是组合)

java - 如何为使用 ActiveMQ Artemis 的服务编写集成测试

java - 从输入流套接字Java读取多行