gpt4 book ai didi

java - 如何重构代码以遵守规则 ‘open-closed’ ?

转载 作者:行者123 更新时间:2023-12-02 01:29:16 25 4
gpt4 key购买 nike

UML 位于此处。不同的产品有不同的优惠策略。
将这些商品添加到购物车时,需要根据其具体的优惠策略,调用'checkout()'方法计算'totalPrice'和'loyaltyPoints'。

但是当新产品有新的优惠策略时,我需要再添加一个“else if”。
我认为这打破了开闭原则。那么你能给我一些关于如何重构代码的建议吗?

 public Order checkout() {
double totalPrice = 0;
Map<String,Integer> buy2Plus1=new HashMap<>();
int loyaltyPointsEarned = 0;
for (Product product : products) {
double discount = 0;
if (product.getProductCode().startsWith("DIS_10")) {
discount = (product.getPrice() * 0.1);
loyaltyPointsEarned += (product.getPrice() / 10);
} else if (product.getProductCode().startsWith("DIS_15")) {
discount = (product.getPrice() * 0.15);
loyaltyPointsEarned += (product.getPrice() / 15);
}else if(product.getProductCode().startsWith("DIS_20")){
discount=(product.getPrice()*0.2);
loyaltyPointsEarned+=(product.getPrice()/20);
}else if(product.getProductCode().startsWith("Buy2Plus1")){
if(buy2Plus1.containsKey(product.getProductCode())){
buy2Plus1.put(product.getProductCode(), buy2Plus1.get(product.getProductCode())+1);
}
else{
buy2Plus1.put(product.getProductCode(),1);
}
if(buy2Plus1.get(product.getProductCode())%3==0){
discount+=product.getPrice();
continue;
}
loyaltyPointsEarned+=(product.getPrice()/5);
}else {
loyaltyPointsEarned += (product.getPrice() / 5);
}
totalPrice += product.getPrice() - discount;
}

return new Order(totalPrice, loyaltyPointsEarned);
}

enter image description here

最佳答案

我会在这里使用工厂模式。首先定义一个接口(interface):

public interface PreferentialStrategy {

String strategyCode();
StrategyResult applyStrategy(Product product);
}

StrategyResult 是一个简单的 pojo,持有折扣和忠诚度积分。

每个策略都是一个实现 PreferentialStrategy 的类:

public class Dis10Strategy implements PreferentialStrategy {

@Override
public String strategyCode() {
return "DIS_10";
}

@Override
public StrategyResult applyStrategy(Product product) {
double discount = product.getPrice() * 0.1;
int points = (int) product.getPrice() / 10;
return new StrategyResult(discount, points);
}
}

与 dis_15、dis_20 等相同。

工厂:

public class StrategyFactory {

private final List<PreferentialStrategy> strategies;
private final PreferentialStrategy defaultStrategy = new NoPrefStrategy();

public StrategyFactory(Collection<PreferentialStrategy> strategies) {
this.strategies = new ArrayList<>(strategies);
}

public void registerPreferentialStrategy(PreferentialStrategy strategy) {
this.strategies.add(strategy);
}

public PreferentialStrategy getStrategy(Product product) {
return this.strategies
.stream()
.filter(strategy -> product.getProductCode().startsWith(strategy.strategyCode()))
.findFirst()
.orElse(this.defaultStrategy);
}

private static final class NoPrefStrategy implements PreferentialStrategy {

@Override
public String strategyCode() {
return "";
}

@Override
public StrategyResult applyStrategy(Product product) {
return new StrategyResult(0, 0);
}
}
}

它获取产品的策略,如果没有,则返回默认策略,没有任何偏好(0折扣和0积分)。每当您需要添加新策略时,只需在工厂中注册即可。

顺便说一句,由于您在这里处理的是金钱,因此您不应该使用 float (它们不精确),而应该使用 BigDecimal

使用示例:

public class TempSecond {

public static void main(String[] args) {
List<Product> products = Arrays.asList(new Product(1000, "DIS_10", "Prod1"),
new Product(1000, "DIS_15_asd", "Prod2"),
new Product(1100, "qwerty", "Prod3"));
StrategyFactory factory = new StrategyFactory(Arrays.asList(new Dis10Strategy(), new Dis15Strategy()));
int loyaltyPointsEarned = 0;
for (Product product : products) {
PreferentialStrategy preferentialStrategy = factory.getStrategy(product);
StrategyResult result = preferentialStrategy.applyStrategy(product);
double discount = result.getDiscount();
loyaltyPointsEarned += result.getLoyaltyPoints();
}
}
}

关于java - 如何重构代码以遵守规则 ‘open-closed’ ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73686067/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com