实现嵌套if语句的另一种方法



我正在尝试重构下面的代码,该代码使用几个嵌套的if语句来检查两个列表是否包含相同的项。

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语句,该语句需要为true才能进行处理,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)
}
}
}

我首先将CarList.get(i)CarRestApiController.data()的结果保存到@T.J.Crowder建议的变量中。然后,我将翻转if检查,并使用continue来消除嵌套。像这样:

List<Car> carList = CarService.findCarByConfigtype(pageName);
for (int i = 0; i < carList.size(); i++) {
Car apiData = CarRestApiController.data();
Car carListData = carList.get(i);
System.out.println(CarRestApiController.data().getModel());
if (!carListData.getModel().equals(apiData.getModel())) {
continue;
}
dataFound.add(carListData.getModel());
if (!carListData.getDerivative().equals(apiData.getDerivative())) {
continue;
}
dataFound.add(carListData.getDerivative());
if (!carListData.getSvp().equals(apiData.getSvp())) {
continue;
}
dataFound.add(carListData.getSvp());
// ... and so on.
}

最新更新