Question

I have a Java application where the domain layer is decoupled from the UI by controllers. The problem is that these controllers can return domain objects, and can have domain objects as parameters.

Some of these returned domain objects are mutable, and this is what I want to prevent. I want it impossible for the UI (or future UI's) to directly modify the domain without accessing the controllers.

I tried two options:

  • In the first one I made sure that each class implemented an 'Unmodifiable' interface which contained only getters. And if I needed to return an object to the UI, I returned its 'Unmodifiable' interface. So that the UI could only view the getters. The problem with this that they still can be cast easily to the original object and access is gained. At first I thought that this level of security was good enough, but it happend that someone accidentally casted some objects and used them in an incorrect way, and integrity was breached.

  • In the second one I tried to provide unmodifiable wrappers for each object that could be returned. But the problem is that these returned objects can be used as parameters for methods in the controllers and so they needed to be unwrapped in the controllers. I tried to make the uwrap() methode package-private, but then I have to put every specific wrapper class in the same package with the controllers and this is a bit inconvenient.

EDIT: 3th option:

  • (With thanks to vic) In the third option the object is wrapped by a unmodifiable wrapper, but can't be unwrapped by this wrapper. Each Unmodifiable is linked to its modifiable object in a Hashmap. So 'unwrapping' is done by getting the modifiable object that is linked to the unmodifiable object.

Does anyone know or has some ideas on how to make objects unmodifiable so they can be returned by a controller, and make it possible to make them modifiable again when they are passed back to the controllers?

Was it helpful?

Solution

What if the controllers store privately the mutable versions of the objects and return immutable versions of it to the "outer world". The mutable versions will have some kind of unique id, and the controllers will be able to unwrap it by looking up in a Collection of some sort.

OTHER TIPS

Go for the State design pattern which is an excellent choice to represent an object's state.

Basically, whenever the UI wants to display a domain object, the controller gives it an immutable DTO object representing a snapshot of the object itself. This will restrict the UI layer to have only immutable snapshots of your domain objects. When the UI wants to make changes to your domain objects, it sends immutable state objects to the controller which use them to internally modify the corresponding domain objects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top