java - Alternative way of implementing nested if statement
问题描述
I am trying to refactor this code I have below that uses several nested if statements to check if two list contains the same items.
List<Car> CarList = CarService.findCarByConfigtype(pageName);
for (int i = 0; i < CarList.size(); i++) {
System.out.println(CarRestApiController.data().getModel());
if (CarList.get(i).getModel().equals(CarRestApiController.data().getModel())) {
dataFound.add(CarList.get(i).getModel());
if (CarList.get(i).getDerivative().equals(CarRestApiController.data().getDerivative())) {
dataFound.add(CarList.get(i).getDerivative());
if (CarList.get(i).getSvp().equals(CarRestApiController.data().getSvp())) {
dataFound.add(CarList.get(i).getSvp());
if (CarList.get(i).getEngine().equals(CarRestApiController.data().getEngine())) {
dataFound.add(CarList.get(i).getEngine());
if (CarList.get(i).getFueltype().equals(CarRestApiController.data().getFueltype())) {
dataFound.add(CarList.get(i).getFueltype());
if (CarList.get(i).getBodystyle().equals(CarRestApiController.data().getBodystyle())) {
dataFound.add(CarList.get(i).getBodystyle());
if (CarList.get(i).getTransmission().equals(CarRestApiController.data().getTransmission())) {
dataFound.add(CarList.get(i).getTransmission());
if (CarList.get(i).getSalescategory().equals(CarRestApiController.data().getSalescategory())) {
dataFound.add(CarList.get(i).getSalescategory());
}
}
}
}
}
}
}
}
}
解决方案
一个解决方案可能是使用策略设计模式。为每个 if 语句制定一个策略,遍历策略列表并处理列表中的每辆车
public interface CarFeatureStrategy {
boolean canProcess(Car carToProcess, Car carToMatch);
Object process(Car carToProcess);
}
该canHandle
方法应封装if语句,该语句需要为真以允许处理,该process
方法应返回汽车相应属性的值(对于描述中的示例应该有8种策略)
public class ModelStrategy implements CarFeatureStrategy {
@Override
public boolean canProcess(Car carToProcess, Car carToMatch) {
return carToProcess.getModel().equals(carToMatch.getModel));
}
@Override
public Object process(Car carToProcess) {
return carToProcess.getModel();
}
}
public class DerivativeStrategy implements CarFeatureStrategy {
@Override
public boolean canProcess(Car carToProcess, Car carToMatch) {
return carToProcess.getModel().equals(carToMatch.getModel())
&& carToProcess.getDerivative().equals(carToMatch.getDerivative());
}
@Override
public Object process(Car carToProcess) {
return carToProcess.getDerivative();
}
}
public class SvpStrategy implements CarFeatureStrategy {
@Override
public boolean canProcess(Car carToProcess, Car carToMatch) {
return carToProcess.getModel().equals(carToMatch.getModel())
&& carToProcess.getDerivative().equals(carToMatch.getDerivative())
&& carToProcess.getSvp().equals(carToMatch.getSvp());
}
@Override
public Object process(Car carToProcess) {
return carToProcess.getSvp();
}
}
// .... and so on for each condition which needs to be met
// EngineStrategy, FueltypeStrategy, BodystyleStrategy,
// TransmissionStrategy, SalescategoryStrategy
CarProcessor
检索与给定对应的汽车,pageName
从 检索数据CarRestApiController
并使用策略列表来处理汽车
public class CarProcessor {
private CarService carService;
private CarRestApiController restController;
private List<CarFeatureStrategy> carFeatureStrategies;
public void processCars(Object pageName) {
// for example purpose the list of strategies is initialized here,
// but it should be initialized somwhere where the initialization is done
// only once rather than each time the processCars method is called
carFeatureStrategies = new ArrayList<>();
carFeatureStrategies.add(new ModelStrategy());
carFeatureStrategies.add(new DerivativeStrategy());
carFeatureStrategies.add(new SvpStrategy());
// ....
// add to the strategies list an instance of each strategy to process
// the car
Car carToMatch = restController.data();
List<Car> cars = carService.findCarByConfigtype(pageName);
List<Object> dataFound = new ArrayList<>();
for (Car carToProcess : cars) {
for (CarFeatureStrategy carFeatureStrategy : carFeatureStrategies) {
if (carFeatureStrategy.canProcess(carToProcess, carToMatch)) {
dataFound.add(carFeatureStrategy.process(carToProcess));
}
}
}
}
}
该示例可以通过实施责任链设计模式进行优化。通过责任链,canHandle
方法中的 if 语句将简化为每个策略只有一个布尔条件。
对于责任链,必须使用返回链中下一个策略的方法来增强策略
public interface CarFeatureStrategy {
boolean canProcess(Car carToProcess, Car carToMatch);
Object process(Car carToProcess);
CarFeatureStrategy next();
}
必须参考链中的下一个策略来增强策略的实施
public class ModelStrategy implements CarFeatureStrategy {
private CarFeatureStrategy nextStrategy;
public ModelStrategy(CarFeatureStrategy nextStrategy) {
this.nextStrategy = nextStrategy;
}
@Override
public boolean canProcess(Car carToProcess, Car carToMatch) {
// check only the model
return carToProcess.getModel().equals(carToMatch.getModel));
}
@Override
public Object process(Car carToProcess) {
return carToProcess.getModel();
}
@Override
public CarFeatureStrategy next() {
return this.nextStrategy;
}
}
public class DerivativeStrategy implements CarFeatureStrategy {
private CarFeatureStrategy nextStrategy;
public DerivativeStrategy(CarFeatureStrategy nextStrategy) {
this.nextStrategy = nextStrategy;
}
@Override
public boolean canProcess(Car carToProcess, Car carToMatch) {
// check only the derivative property
return carToProcess.getDerivative().equals(carToMatch.getDerivative());
}
@Override
public Object process(Car carToProcess) {
return carToProcess.getDerivative();
}
@Override
public CarFeatureStrategy next() {
return this.nextStrategy;
}
}
// ... and so on for all the strategies
CarProcessor
应该建立一个策略链并处理每辆汽车,直到链完成(当前策略的方法next
返回null)或当前策略无法处理当前汽车(canHandle
当前策略的方法返回false)
public class CarProcessor {
private CarService carService;
private CarRestApiController restController;
public void processCars(Object pageName) {
// for example purpose the chain of responsibilities is initialized here,
// but it should be initialized somwhere where the initialization is done
// only once rather than each time the processCars method is called
// initialise the chain of responsibilities in revers order
CarFeatureStrategy salesCategoryStrategy = new SalescategoryStrategy(null);
CarFeatureStrategy transmissionStrategy = new TransmissionStrategy(salesCategoryStrategy);
CarFeatureStrategy bodystyleStrategy = new BodystyleStrategy(transmissionStrategy);
CarFeatureStrategy fueltypeStrategy = new FueltypeStrategy(bodystyleStrategy);
CarFeatureStrategy engineStrategy = new EngineStrategy(fueltypeStrategy);
// .... and so on until the first strategy in the chain
CarFeatureStrategy modelStrategy = new ModelStrategy(...);
Car carToMatch = restController.data();
List<Car> cars = carService.findCarByConfigtype(pageName);
List<Object> dataFound = new ArrayList<>();
for (Car carToProcess : cars) {
CarFeatureStrategy currentStrategy = modelStrategy;
do {
if ( !currentStrategy.canProcess(carToProcess, carToMatch)) {
// if current strategy cannot process the current car
// stop the chain
break;
}
dataFound.add(currentStrategy.process(carToProcess));
// move to the next strategy in the chain
currentStrategy = currentStrategy.next();
} while (currentStrategy != null)
}
}
}
推荐阅读
- python - Python 神经网络中不需要的 [Nan] 输出
- vue.js - 在 style 属性中使用 props 值
- angular - Angular 8滚动到片段,不会将片段带到页面顶部
- c++ - 如何在不更改第一项的情况下通过引用将 2 项传递给函数
- c# - 将 Microsoft Bot Framework 与 ASP.NET Core 2.2 结合使用
- node.js - 如何从 azure-pipeline.yml 运行 node.js 文件?
- trace - 运行单元测试时无法在输出窗口中显示跟踪消息
- android - 如何在卡片视图中获取文本视图的引用
- angular - TypeScript 中的等价物列表
- vpn - 如何使用 xfrm 设置站点到站点 VPN 隧道