Решением может быть использование Шаблон проектирования стратегии .Иметь стратегию для каждого оператора 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));
}
}
}
}
}
Пример можно оптимизировать с помощью шаблона проектирования Цепочка ответственности .При цепочке ответственности операторы if в методах canHandle
будут упрощены до одного булевого условия для стратегии.
Для цепочки ответственности стратегии должны быть расширены с помощью метода, который возвращает следующую стратегию вchain
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
вернет ноль) или текущая стратегия не сможет обработать текущий автомобиль (метод текущей стратегии * 1030 вернет 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)
}
}
}