【问题标题】:DDD Aggregate root, wich way to create new child aggregate elements with different types? Factory method? [closed]DDD聚合根,用什么方式创建不同类型的新子聚合元素?工厂方法? [关闭]
【发布时间】:2018-12-19 10:02:42
【问题描述】:

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

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

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 方法吗?其他选择?谢谢朋友!

【问题讨论】:

    标签: java php oop domain-driven-design aggregateroot


    【解决方案1】:

    作为聚合满足促销的规则

    嗯,一个 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); }
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多