首页 > 解决方案 > 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());
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

标签: javalistobjectif-statement

解决方案


一个解决方案可能是使用策略设计模式。为每个 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)
        }
    }
}

推荐阅读