Exposing collections: paranoia vs trust approaches
Whenever a class in my model contains a collection which requires that particular care be taken with its items, there's an internal debate regarding how to expose it to other classes. And with this, there are two major schools: one, the paranoia-based approach which doesn't allow external code to touch the collection's internal items and two, the trusting approach which just returns the collection for everyone to deal with.
What are your thoughts on the matter? What do you use, when and why?
The paranoia approach
The paranoia approach retains the collection modifications inside the class. Want to add a value? Sure, but through an addItem method. Remove a value? Go ahead: removeItem. Get the collection itself? No problem at all, getItems will return the result of the Collections.unmodifiableCollection method. You get the picture. The benefits are simple: the class controls the collection. Throwing an exception when an item is added which is not logically correct for the collection to contain or firing an event when an item is removed can be easily programmed when the methods are implemented within the class. And no need to worry about pesky wrong code creating bugs by clearing the collection "accidentally" - yes, we know it wasn't an accident, and you know who you are!The trusting approach
The trusting approach assumes that the user of the class knows what they're doing. In effect, there are two methods: getItems implemented asreturn items and setItems implemented as this.items = items. As simple as that. This can be great when you want your code to be simple, but more importantly when you want to use dependency injection or object-relational mapping frameworks. For example, currently Hibernate behaves strangely when the collection returned from a getter is different than the one Hibernate set originally using the setter.
Pros and Cons
I guess it's time for a comparison table:| Use | Paranoia approach | Trust approach |
|---|---|---|
| Maintenance | A lot of boiler-plate code really makes this difficult to maintain | Simple code |
| Exporting the class as part of an API | Since the class is foolproof, there's no fear of an accidental change of the collection by a third party developer | Not recommended unless contents of collections can be changed without causing major bugs |
| Using as a part of an internal model representation | Difficult to map to an ORM or DI solution | Easy to use as this is a classic POJO implementation |
What are your thoughts on the matter? What do you use, when and why?
Comments (16)