假设我们有一个领域对象和该对象的评估类。例如,单独类中的促销及其评估逻辑:
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/