假设我们有一个域对象和该对象的评估类。例如在单独的类中的促销及其评估逻辑:
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原理来配对这些对。
答案 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);
}
}
}