java - 将域对象与业务逻辑结合起来

标签 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
           }
        }
    }
}

我们有很多这样的对。

我们无法将评估注入(inject)域对象中,但我们可以在评估类或其他类中将它们关联起来。

第一个选项是将它们与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)模型领域驱动设计方式

通过使域对象具有行为,您可以使事情变得更简单。
例如,您可以将促销和促销评估合并到一个类中。
贫血的物体不一定是最好的东西。
例如:

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 可以是一个接口(interface),定义逻辑模板以及在子类中定义的抽象 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);
        }
    }
}

关于java - 将域对象与业务逻辑结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55001253/

相关文章:

java - 从外部 jar 或外部类路径动态加载映射实体

Java-将字符串分割成数组

java - 在 Eclipse 中创建新的 Maven 项目时显示的错误

java - (Spring Boot 2)java.lang.IllegalStateException : Failed to load ApplicationContex

java - 如何在端点函数体内检索请求方法?

spring - Spring MVC 中 @RequestParam 的自定义转换器

java - 在 Java 中创建 map

java - 在 GlassFish 中配置 jdbcRealm 的表命名约定

java - 无法通过 Apache commons csv 读取更多记录

java - Thymeleaf - 将变量传递给 Controller