假设我们有一个域对象和该对象的评估类。例如,促销及其在分离类中的评估逻辑:
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)模型域驱动的设计方式
通过使域行为具有行为,您可以更简单地做事。 例如,您可以在单个班级中合并促销和促销评估。 贫血对象不一定是最好的东西。 例如 :
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);
}
}
}