将域对象与业务逻辑耦合

时间:2019-03-05 10:58:54

标签: java spring spring-boot java-8

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

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原理来配对这些对。

1 个答案:

答案 0 :(得分: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);
        }
    }
}