sfreaky
@sfreaky
Начинающий веб и софт разработчик

Как написать generic фабрику?

Есть иерархия классов моделей из бд.
class Car {
    private String name;
}
class Ford extends Car {
    private String name;
}
class Audi extends Car {
    private String name;
}

Для каждой модели нужен класс который принимает как аргумент один из наследников и возвращает Object
class FordHandler {
    Object handle(Ford ford) {
        return new Object();
    }
class AudiHandler {
    Object handle(Audi ford) {
        return new Object();
    }
}

Где-то снаружи должен быть похожий на этот
List<Car> carList;
List<Object> result;
carList.forEach((car) -> {
    result.add(factory.get(car.getClass()).handle(car));
})

Как правильно это реализовать?
  • Вопрос задан
  • 405 просмотров
Пригласить эксперта
Ответы на вопрос 2
jamakasi666
@jamakasi666 Куратор тега Java
Просто IT'шник.
Если я правильно понял задачу то что то типа такого.
public interface Handler<T> {
  Object handle(T obj);
}
class FordHandler implements Handler<Ford>{...}
/// в фабрику
Map<Class<T>, Handler<T>> registry = new HashMap<>();
public void registerHandler(Class<T> carType, Class<? extends Handler> handlerType) {
    registry.put(carType, handlerType);
}
public <T> Handler<T> getHandler(Class<T> clazz) {
  return registry.get(clazz).newInstance();
}
///наполняешь фабрику
factory.registerHandler(Ford.class, FordHandler.class);
factory.registerHandler(Audi.class, AudiHandler.class);
///
List<Car> carList;
List<Object> result;
carList.forEach((car) -> {
    result.add(factory.getHandler(car.getClass()).handle(car));
})
Ответ написан
Комментировать
@distrik
Programador
На вскидку не придумал, как избавиться от @SuppressWarnings("unchecked"), может только пойти другим путем.

public class Main {
  @SuppressWarnings("unchecked")
  public static void main(String[] args) {
    Map<Class<? extends Car>, Handler> carHandlers = new HashMap<>();
    carHandlers.put(Car.class, new CarHandler());
    carHandlers.put(Ford.class, new FordHandler());
    Car car = new Car();
    Car ford = new Ford();
    Object carTest = carHandlers.get(car.getClass()).handle(car);
    Object fordTest = carHandlers.get(ford.getClass()).handle(ford);
    System.out.println(carTest);
    System.out.println(fordTest);
  }

  interface Handler<T extends Car> {
    Object handle(T obj);
  }

  static class Car {
    String test() {
      return "I'm Car";
    }
  }

  static class Ford extends Car {
    String test() {
      return "I'm Ford";
    }
  }

  static class CarHandler implements Handler<Car> {
    @Override
    public Object handle(Car car) {
      return car.test();
    }
  }

  static class FordHandler implements Handler<Ford> {
    @Override
    public Object handle(Ford ford) {
      return ford.test();
    }
  }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы