Должны ли объекты домена веб-приложения, содержащие коллекции, иметь методы добавления и удаления элементов? - PullRequest
1 голос
/ 06 мая 2009

Допустим, у меня есть класс Person, у которого есть коллекция объектов Dog. Отношения двунаправленные.

public class Person {
  private List<Dog> dogs;
  // getter and setter for dogs
}

public class Dog {
  private Person person;
  // getter and setter for person
}

Хорошо, если бы я просто работал с этими объектами, у меня в Person были бы методы для добавления собаки и удаления собаки, чтобы клиент не работал напрямую с коллекцией.

public void removeDog(Dog dog) {
  dogs.remove(dog);
  dog.setPerson(null);
}

public void addDog(Dog dog) {
  dog.setPerson(this);
  dogs.add(dog);
}

или что-то в этом роде.

Мой вопрос возникает при работе с этими объектами в слое сервиса. Я могу добавить новую собаку к человеку через addDog и просто сохранить человека, который автоматически сохранит новую собаку. Тем не менее, удаление собаки с помощью removeDog и последующее сохранение этого лица не приведет к автоматическому удалению собаки из постоянного хранилища ... для нее будет просто задано нулевое указание собаки.

Итак, я получаю что-то вроде:

Dog dog = dogDAO.getDogById(int id);
dogDAO.remove(dog);

Поскольку это веб-приложение, а Персоны и Собаки не сохраняются в памяти, это прекрасно работает, и я никогда не вызывал Person.removeDog (). В следующий раз, когда я загружу Человека, который изначально ссылался на эту собаку, она не будет содержать собаку, потому что она была удалена из хранилища. То же самое относится и к добавлению собаки:

Person person = personDAO.getPersonById(int id);
Dog dog = new Dog();
dog.setPerson(person);
dogDAO.save(dog);

Опять же, это прекрасно работает, и я никогда не вызывал Person.addDog ().

Есть ли смысл использовать методы addDog и removeDog в моем классе Person?

Ответы [ 2 ]

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

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

Звучит так, как у вас, все хорошо, ясно и недвусмысленно. Если вы хотите, вы всегда можете добавить комментарий к классу Dog, чтобы добавить, что целесообразно, чтобы не было методов addPerson и removePerson, и что вместо этого это следует сделать, удалив собаку из человека или добавив собаку в человека.

Нет необходимости в идеальной симметрии или идеальной ортогональности в коде. Цель не в этом, а в поддержании согласованности вашей модели данных в понятной и понятной форме.

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

Это всегда трудно сделать без ручного вмешательства. После того, как вы удалите ссылку на объект и получите устаревший объект. В другом случае вы просто удаляете объект, на который указывает какой-то другой объект (список). Это тоже должно быть проблемой. Если это будет принято лениво, это покроет много ошибок.

Для простоты вы можете добавить операцию dao remove к человеку removeDog (), но тогда вариант использования, удаляющий собаку из одного человека и добавляющий ее к другому, будет невозможен. В чем проблема, что вы удаляете собаку от человека, а затем удаляете ее из упорства, если знаете, что ее вообще нужно удалить? Вы экономите один шаг. Таким образом, возвращение удаленной собаки принесет вам шаблон

dogDAO.remove(person.removeDog(dog))

Личное добавление и удаление позволяет вам не только имитировать поведение списка, но и иметь некоторые дополнительные функции. В вашем случае это трудно решить, потому что это простая установка, и она зависит от того, насколько доступным является материал дао и где вы хотите его разместить.

По крайней мере, у вас должно быть впечатление о каждом конкретном случае использования, который вы хотите поддержать. Затем необходимо определить обязательные и необязательные ссылки на объекты и настройки. При некотором прагматизме (например, связывая персистентность с объектами) у нас есть шанс сделать более объектно-ориентированную настройку, которую легко (и поэтому менее подвержено ошибкам) ​​использовать

...