我正在尝试重构下面的代码,该代码使用多个嵌套的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());
}
}
}
}
}
}
}
}
}
答案 0 :(得分:2)
一个解决方案可能是使用Strategy design pattern。为每个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));
}
}
}
}
}
可以通过实现Chain of responsibility design pattern对示例进行优化。有了责任链,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
方法返回空值)或当前策略无法处理当前车({{ 1}}当前策略的方法返回false)
canHandle
答案 1 :(得分:1)
我首先按照@ T.J.Crowder的建议将CarList.get(i)
和CarRestApiController.data()
的结果保存到变量中。然后,我将翻转if-checks并使用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.
}