Итак, все то же самое, за исключением
- типов DTO, в которые вы копируете данные (VehicleVuScores vs DriverVuScores)
- вызванный метод RestClient
Основная проблема - поделиться кодом, который вызывает сеттеры.Нам нужен способ ссылаться на целевой объект, не зная, является ли он VehicleVuScores или DriverVuScores.Мы могли бы объявить это как:
Object vuScores;
, но поскольку Object
не объявляет сеттеры, мы получим ошибки компиляции при попытке вызвать сеттеры.Чтобы исправить это, мы можем переместить объявление этих методов получения и установки в общий базовый тип:
abstract class VuScoresBase {
// fields, getters and setters
}
class DriverVuScores extends VuScoresBase {}
class VehicleVuScores extends VuScoresBase {}
, поэтому мы можем написать:
public void convert(VehicleUtilization vehicleUtilization, VuScoresBase result) {
// invoke the setters here
}
и использовать этот метод в обоих случаях.
С помощью дженериков мы могли бы также повторно использовать код итерации:
<V extends VuScoresBase> public void convertList(List<VehicleUtilization> vehicleUtilizations, List<V> resultList, Supplier<V> constructor) {
// iterate
V vuScore = constructor.apply();
convert(vehicleUtilization, vuScore);
resultList.add(vuScore);
}
, чтобы мы могли вызывать его с помощью
convertList(vehicleUtilizations, driverVuScores, DriverVuScore::new);
, но я бы, вероятно, воздержался от этогоПотому что из-за непатентованного кода код становится трудным для понимания.
Однако, поскольку DriverVuScores и VehicleVuScores очень похожи, я бы задал вопрос, действительно ли они должны быть отдельными типами.Если бы мы могли использовать VuScoresBase везде, это значительно упростило бы логику преобразования:
VuScoresBase convert(VehicleUtilization vehicleUtilization) {
VuScoresBase vuScores = new VuScoreBase();
// invoke setters
return vuScores;
}
и
List<VuScoresBase> convertList(List<VehicleUtilization> vehicleUtilizations) {
// iterate
result.add(convert(vehicleUtilization));
}