Создать объект одного типа из объекта другого типа с поиском в базе данных - PullRequest
1 голос
/ 27 марта 2019

У меня есть приложение, которое получает автомобильный объект из сторонней базы данных.Я называю сущность ThirdPartyCar.Моему приложению необходимо создать объект Car, используя данные из ThirdPartyCar.Тем не менее, сущность Car должна также получить некоторые из своих данных из базы данных моего приложения.Например, состояние ThirdPartyCar может быть _BOUGHT, и через поиск в базе данных мое приложение должно преобразоваться в Sold.

. В настоящее время у меня есть конструктор Car, имеющий аргумент ThirdPartyCar,Но конструктор Car не может заполнить данные поиска, поскольку он является сущностью, и сущности не должны иметь ссылку на репозитории.Итак, у меня также есть сервис для заполнения оставшихся данных:

public class ThirdPartyCar {
    @Id
    private Long id;
    private String vin;
    private String status;
    // more props + default constructor
}

public class Car {
    @Id
    private Long id;
    private String vin;
    private CarStatus status;
    // more props (some different than ThirdPartyCar) + default constructor

    public Car(ThirdPartyCar thirdPartyCar) {
       this.vin = thirdPartyCar.getVin();
       // more props set based on thirdPartyCar
       // but props leveraging database not set here
    }

 public class CarStatus {
    @Id
    private Long id;
    private String status;
 }

 public class CarBuilderService {
     private final CarStatusMappingRepository repo;

     public Car buildFrom(ThirdPartyCar thirdPartyCar) {
        Car car = new Car(thirdPartyCar);
        CarStatus status = repo.findByThirdPartyCarStatus(thirdPartyCar.getStatus());
        car.setStatus(status);
        // set other props (including nested props) that depend on repos

     }
  }

Логическим местом для создания Car на основе ThirdPartyCar является конструктор.Но у меня есть разрозненный подход, потому что я нуждаюсь в репо.Какой шаблон можно применить таким образом, чтобы все данные создавались в конструкторе, но при этом объект не знал о репозиториях?

1 Ответ

1 голос
/ 27 марта 2019

Вам не следует связывать два POJO класса из разных доменов в constructor. Эти два класса не должны ничего знать друг о друге. Может быть, они представляют одну и ту же концепцию в двух разных системах, но они не одинаковы.

Хороший подход заключается в создании интерфейса Abstract Factory, который будет использоваться везде, где Car должно быть создано из ThirdPartyCar:

interface ThirdPartyCarFactory {

    Car createNewBasedOn(ThirdPartyCar source);
}

и одна реализация может быть вашей RepositoryThirdPartyCarFactory:

class RepositoryThirdPartyCarFactory implements ThirdPartyCarFactory {

    private CarStatusMappingRepository repo;
    private CarMapper carMapper;

    public Car createNewBasedOn(ThirdPartyCar thirdPartyCar) {
        Car car = new Car();
        carMapper.map(thirdPartyCar, car);

        CarStatus status = repo.findByThirdPartyCarStatus(thirdPartyCar.getStatus());
        car.setStatus(status);
        // set other props (including nested props) that depend on repos

        return car;
    }
}

В приведенной выше реализации вы можете найти CarMapper, который знает, как сопоставить ThirdPartyCar с Car. Для реализации этого картографа вы можете использовать Dozer , Orika , MapStruct или вашу собственную реализацию.

Другой вопрос, как вы получили ThirdPartyCar объект. Если вы загрузите его на ID из ThirdPartyRepository, вы можете изменить свою абстрактную фабрику на:

interface CarFactory {
    Car createNew(String id);
}

и данная реализация загружается на ID ThirdPartyCar и отображает его на Car. Все скрыто фабрикой, которую вы легко можете обменять.

Смотри также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...