M
M
Mozzarella2019-02-10 13:17:07
MySQL
Mozzarella, 2019-02-10 13:17:07

How to write a generic factory?

There is a hierarchy of classes of models from the database.

class Car {
    private String name;
}
class Ford extends Car {
    private String name;
}
class Audi extends Car {
    private String name;
}

Each model needs a class that takes one of the heirs as an argument and returns Object
class FordHandler {
    Object handle(Ford ford) {
        return new Object();
    }
class AudiHandler {
    Object handle(Audi ford) {
        return new Object();
    }
}

Somewhere out there must be something like this
List<Car> carList;
List<Object> result;
carList.forEach((car) -> {
    result.add(factory.get(car.getClass()).handle(car));
})

How to implement it correctly?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
S
Sanan Yuzb, 2016-07-28
@Sanan07

WHERE Услуга not in ('У5')

P
Pavel, 2016-07-29
@Ermako

Let's say we have a clients table with client_id and service_id fields.
Logic: we find everyone who has a service, make a join and weed out those who did not fall under the join condition.

select distinct c.client_id
from clients c
left join (select client_id
                  from clients
                      where service_id = 5) s on s.client_id = c.client_id
where s.client_id is null

D
Dmitry Alexandrov, 2019-02-10
@jamakasi666

If I understand the problem correctly then something like this.

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));
})

M
Marat Khayrutdinov, 2019-02-12
@distrik

Offhand, I haven't figured out how to get rid of @SuppressWarnings("unchecked") , I can only go the other way.

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();
    }
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question