Should web application domain objects containing collections "add" and "remove" member methods?

Let's say I have a Person class that has a collection of Dog objects. The relationship is bi-directional.

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

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

      

Okay, if I were just working with these objects, I would have methods in Person to add a dog and remove a dog so that the client doesn't work directly with the collection.

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

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

      

or something like that.

My question comes up when working with these objects in the service layer. I can add a new dog to a person via addDog and just save the person, which will automatically save the new dog. However, removing the dog with removeDog and then saving that face will not automatically remove the dog from persistent storage ... it will just set the dog reference to null.

So I end up with something like:

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

      

Because this is a web application and people and dogs are not stored in memory, this works great and I never called Person.removeDog (). The next time I upload the Human that originally referenced this dog, it will not contain the dog because it has been removed from storage. The same can be applied to adding a dog:

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

      

Again this works great and I never called Person.addDog ().

Does it make sense to use the addDog and removeDog methods in my Person class?

+1


a source to share


2 answers


It is always difficult to do this without manual intervention. After removing the reference to the object and having a stale object. In another use case, you are simply deleting an object that other objects belong to (a list). This is also a problem. If accepted lazily, it will cover a lot of errors.

For simplicity's sake, you can add a remove dao operation for a person removeDog (), but then a use case removing a dog from one person and adding it to another would be impossible. What is the problem that you remove the dog from the person and then remove it from persistence if you know you need to remove it at all? You will spare one step. Therefore, returning the remote dog will bring you a sample

dogDAO.remove(person.removeDog(dog))

      



Having add and remove allows you to not only mimic the behavior of a list, but also have additional functionality. In your case, this is difficult to solve because it is a simple setup and it depends on how accessible the dao stuff is and where you want to do it.

You should have at least an impression for every use case you want to support. Then you need to specify the required and optional links and object settings. With some pragmatism (like binding persistence stuff to objects), we need to do another object oriented setup that's easy (and therefore less error prone) to use

+1


a source


If logically adding and removing dogs in humans is how it would be done, then there is no reason to have methods for adding and removing humans from dogs. Your goal is to keep your data model always in a persistent state. If you allow people to be removed from dogs, you will need to remove dog from person to keep your data model consistent. Then you have to avoid recursion.

Sounds like yours is good, clear and unambiguous. If you want, you can always add a comment to the Dog class to add that it makes sense that there is no addPerson and removePerson method, and that this should be done by removing the dog from the person or adding the dog to the person.



No need for perfect symmetry or perfect orthogonality in your code. The goal is not for this, but for your data model to be consistent in a clear and understandable way.

+1


a source







All Articles