与业务逻辑的夫妇领域对象

问题描述 投票:2回答:1

假设我们有一个域对象和该对象的评估类。例如,促销及其在分离类中的评估逻辑:

class BuyXGetYFreePromotion extends AbstractPromotion{
   String x;
   String y;
}

class BuyXGetYFreePromotionEvaluation {
   public void evaluate(Cart cart){
       for(String product : cart.getProducts()){
           if(product.equal(BuyXGetYFreePromotion.x)){
              //some code to discount y price
           }
       }
   }
}

另一个例子:

class FixedPricePromotion extends AbstractPromotion{
    String product;
    Double price;
}

class FixedPricePromotionEvaluation {
    public void evaluate(Cart cart){
        for(String product : cart.getProducts()){
           if(product.equal(FixedPricePromotion.product)){
              //some code to discount y price
           }
        }
    }
}

我们有很多像这样的对。

我们不能在域对象中注入评估,但我们可以将它们与评估类或其他类相关联。

第一个选项是将它们与instanceof语句联系起来。

例如:

class PromotionService {
    void evaluation(Cart cart){
        for(AbstractPromotion p : getPromotions){
            if(p instanceof BuyXGetYFreePromotion)
               BuyXGetYFreePromotionEvaluation.evaluate(cart);
            else if(p instanceof FixedPricePromotion)
               FixedPricePromotionEvaluation.evaluate(cart);
        }
    }
}

但是这个例子违反了开放原则。

我的问题是,我应该如何通过考虑SOLID原则来结合这些对。

java spring spring-boot java-8
1个回答
2
投票

1)模型域驱动的设计方式

通过使域行为具有行为,您可以更简单地做事。 例如,您可以在单个班级中合并促销和促销评估。 贫血对象不一定是最好的东西。 例如 :

class FixedPricePromotion extends AbstractPromotion{
    String product;
    Double price;
    public void evaluate(Cart cart){
        for(String product : cart.getProducts()){
           if(product.equal(product)){
              //some code to discount y price
           }
        }
    }    
}

现在可以通过这种方式更改PromotionService:

class PromotionService {
    void evaluation(Cart cart){
        for(AbstractPromotion p : getPromotions){                
               p.evaluate(cart);
        }
    }
}

2)模型域和逻辑分离方式

如果你不想合并它们,你可以通过从一个到另一个的字段依赖来桥接它们。

PromotionEvaluation可以是定义逻辑模板的接口,抽象isMatch()applyPromotion()方法在子类中定义:

public interface PromotionEvaluation{

       boolean isMatch(String product);
       void applyPromotion(String product);
       default void evaluate(Cart cart){
            for(String product : cart.getProducts()){
               if(isMatch(product)){
                  applyPromotion(product);
               }
            }
        }       
}

子类可以是这样的:

class FixedPricePromotionEvaluation implements PromotionEvaluation{
    FixedPricePromotion promotion;

    public FixedPricePromotionEvaluation(FixedPricePromotion promotion){
      this.promotion = promotion;
    }

    public boolean isMatch(String product){
       return product.equal(promotion.product)
    }

    public void applyPromotion(String product){
      // do your logic
    }


}

现在,您可以通过以下方式迭代评估:

class PromotionService {
    void evaluation(Cart cart){
        for(PromotionEvaluation evaluation : getEvaluations()){
            e.evaluate(cart);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.