Классы ORM с коллекциями; пытаясь сосредоточиться на родительском классе, а не на детях - PullRequest
0 голосов
/ 18 мая 2009

Допустим, у меня есть класс Farmer, а у Farmer есть коллекция Pigs.

Если я использую ORM, такой как Hibernate, я могу каскадно обновлять коллекцию Свинья Фермера, чтобы я мог сделать что-то подобное с моего контроллера:

Pig pig = new Pig("Charlie");
farmer.addPig(pig);
farmerService.save(farmer);

Моя служба фермеров ничего не знает о свиньях. В зависимости от требований приложения, мне может даже не понадобиться Pig DAO. Я занимаюсь только фермерами.

Круто, но что происходит, когда Свинья превращается в бекон?

farmer.removePig(pig);
farmerService.save(farmer);

Проблема здесь в том, что в веб-приложении без состояния мне нужен какой-то способ создания Pig, который я собираюсь передать методу removePig фермера.

Я мог бы сделать:

// manual search Farmer's collection - requires loading all pigs.
// Yes, I could just pass id to removePig, but it confuses the example
pig = farmer.getPigById(id);
farmer.removePig(pig);
farmerService.save(farmer);

или

// loads up a pig, and hopefully it belongs to the farmer
pig = farmerService.getPigById(id);
farmer.removePig(pig);
farmerService.save(farmer);

Последнее кажется лучше, но если я собираюсь добавить метод getPigById () в мой farmerService, я мог бы также просто иметь метод savePig (). Это изменит фокус с фермера на свинью.

pig = farmerService.getPigById(id);
farmerService.removePig(pig);

Ага, и посмотрите, это еще меньше кода. Однако это нарушает логическое представление о желании работать с фермерами и их коллекциями свиней, а не с отдельными свиньями. Я больше не удаляю Свинью явно из фермера, все это неявно и наоборот.

Кажется, я много сталкиваюсь с этой проблемой. Класс, который должен быть в центре внимания - это Фермер. Свиньи вторичны. Но трудно работать с коллекциями свиней, не скатываясь вниз по склону к работе с отдельными свиньями, изменения которых просто отражаются, когда фермеры перезагружаются от постоянства.

Какой совет вы можете мне дать по этому вопросу?

1 Ответ

1 голос
/ 18 мая 2009

В сценарии я склоняюсь к вашему второму подходу. Тот факт, что вы находитесь в среде без состояний, не должен отражаться в вашей объектной модели, а только в том, как вы восстанавливаете свое состояние в конкретном http-запросе. Это сделано здесь:

pig = farmerService.getPigById(id);

Этот код должен появляться в контроллере (в пределах шаблона MVC или MVP). Затем остальная часть кода продолжается, как обычно:

farmer.removePig(pig);
farmerService.save(farmer);

Конкретный контроллер, который обрабатывает текущий запрос, должен нести ответственность за поддержание этого состояния текущего рассматриваемого объекта. Он должен отвечать за отправку идентификатора свиньи в браузер и за перевод этого идентификатора свиньи в объект свиньи. То, как он это делает, является его собственным, но использование звонка в службу фермера имеет смысл. Отсюда вы можете дополнительно автоматизировать этот перевод, используя общий вызов id-to-object и наоборот.

Ваше мнение о том, что эта модель предметной области должна быть ориентирована на фермеров, является правильным и согласуется с дизайном, управляемым доменом. Класс Farmer в этом случае представляет собой совокупность свиней, и поэтому определяет границу вокруг набора свиней. Все свинки должны пройти через фермера. Таким образом, у вас есть четкий контракт о том, как свиньи создаются, уничтожаются и модифицируются. Поэтому ваш последний подход не такой здравый, как предыдущий.

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