Соединение доменного объекта с бизнес-логикой - PullRequest
2 голосов
/ 05 марта 2019

Предположим, что у нас есть объект домена и оценочный класс этого объекта.Например, продвижение и его логика оценки в отдельных классах:

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);
        }
    }
}

Но этот пример нарушает принцип Open-Closed.

У меня вопрос, как мне соединить эти пары, учитывая принципы SOLID.

1 Ответ

2 голосов
/ 05 марта 2019

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);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...