2015-11-22 3 views
3

Приводим пример ниже:Дизайн Java POJO с ленивой загрузкой

Веб-приложение создает объект пользователя для каждого зарегистрированного пользователя. Этот объект имеет простые String свойства для firstName, lastName ...

Каждый пользователь может иметь car. Считайте, что выборка пользователя car очень дорога, поэтому мы предпочитаем не устанавливать пользовательский автомобиль, когда пользователь входит в систему. Вместо этого мы хотим получить автомобиль, когда это необходимо.

Для реализации этого мы создали пользователя POJO как:

public class User() { 
    private String FirstName; 
    private String LastName; 
    private Car car; 
    //Here we have the service object, this could be injected with spring or JEE 
    private CarServices carServices; 

    public Car getCar() { 
    //If the car is not fetched yet, go on and get it from your service 
    if (car == null) { 
     car = carServices.getCarFromDB(...) 
    } 
    return car; 
    } 

} 

Для первоначального пользователя после входа в систему:

User newUser = new User(); 
newUser.setFirstName("foo"); 
newUser.setLastName("bar"); 
//We just let user have service, so he can use this service latter 
newUser.setCarServices(new CarServices()); 

И каждый прецеденту, который нуждается в пользовательский автомобиль может легко получить его:

newUser.getCar() 

Однако, я утверждал, что таким образом мой объект User больше не является простым pojo и это не очень хороший подход.

Как я могу достичь этого требования лучше.

+0

Вы объявили 'Car' как' cars', но позже использовали 'car' в качестве переменной, это опечатка? если да, исправьте. – Blip

+0

Если класс пользователя должен инкапсулировать способ получения автомобиля, то код, который у вас есть, - это путь. Если получение автомобиля - это то, что пользователь не должен знать, то используйте классическую парадигму setCar/getCar. Затем, контракт заключается в том, чтобы пользовательские клиенты устанавливали автомобиль до того, как они получили автомобиль, а клиенты должны обрабатывать нулевой ответ getCar. - Кроме того, пользователь POJO и подкласс UserWithCar может быть подходом - зависит от вашего общего дизайна, предпочитаете ли вы это делать. – laune

ответ

3

Я утверждал, что таким образом мой объект Пользователь не простой POJO

Чтобы Anwer ваш вопрос, я хотел бы прежде всего вернуться немного в историю.

Pojo является простой старый объект java и означает, что вы используете только «стандартную» java. Этот термин был создан в то время, когда J2EE имел обман. В это время разработчики закодировали бизнес-логику в корпоративных бобах, и этим EJBs понадобилось много кода инфраструктуры. Этот факт связан логикой логики с технологией внедрения. Итак, Ребекка Парсонс, Джош Маккензи и Мартин Фаулер пришли к выводу, что бизнес-логика будет более многократно использоваться и легче тестировать, если вы просто используете стандартную Java. Таким образом, они создали термин pojo, потому что разработчики любят причудливые имена.

Ваш класс User зависит только от стандартного Java и поэтому это POJO.

Некоторые разработчики утверждают, что pojo не должно содержать никакой логики. Эти разработчики предпочитают анемичные модели. Другие говорят, что богатая модель - лучший подход. Я принадлежу разработчикам, которые предпочитают богатую модель по анемичной модели.

Если вы хотите удалить CarServices зависимости от User класса можно реализовать Car отложенной загрузки прокси так же, как спящий режим или JPA реализация делает.

По крайней мере, вот некоторые из моих мыслей о фасоли, пожо, анемии и богатых моделях домена.

Надеюсь, это поможет вам, когда вы обсуждаете Жека других разработчиков.

1

Вместо ссылки на автомобиль вы можете использовать ссылку на объект поставщика автомобилей, реализация которого может кэшировать полученный первый результат (см. Классы Guava's Supplier и MemoizingSupplier). Таким образом, вы скрываете от объекта User тот факт, что его автомобиль может присутствовать или не присутствовать во время создания экземпляра и, следовательно, сделать его реализацию проще (в логике метода больше нет логики).

Другим преимуществом этого решения было бы разбить соединение между классами User и CarServices (больше не нужно для свойства carServices). Можно ввести поставщика, реализация которого вернет ссылку на уже доступный объект Car, в то время как другой может передать реализацию, которая переадресует вызов службе CarServices.

Это не сделало бы класс User более POJO, хотя (как объяснялось в первом ответе выше), но люди, которые спорили с вашим решением, могут понравиться этому лучше, потому что он проще и менее тесно связан.

Смежные вопросы