I've been thinking about this for a while during my past development.
I am kind of against doing such things, I've normally declared a separate method that explicitly handle the logic.
E.g.
If a Class has a method which return a list of objects, I think it is a bad idea to modify this collection directly via its getter method.
Public Class ReportGenerator{
private List<Configurations> configurations;
List<Configuration> getConfigurations (){
return this.configurations;
}
}
I think by doing the following is bad practice:
getConfigurations().remove(1); //remove a configuration via a getter
I would use the following appoach:
Public Class ReportGenerator{
private List<Configurations> configurations;
public List<Configuration> getConfigurations (){
return Collections.unmodifiableList(this.configurations);
}
public void removeConfiguration(int index) //logic explicitly handle the remove
{
this.configurations.remove(index);
}
}
However there is one more thing just comes to my mind is that what if Configuration object also has getter and setter, then you can't prevent others by doing
reportGenerator.getConfigurations().get(0).settTitle("test");
They can still change the state of Configuration object by using the getter method of ReportGenerator, which I think it shouldn't allow that. But if we want to prevent this we would have to declare more methods in the ReportGenerator class to forward the call to the Configuration object, and use defensive copy.
So my question is that if you have a object A which contains another object B using composition and they both have getter and setter, do you prefer to change object B's state via A's getter method? E.g.
A.getB().setTitle("");
or do you prefer to add method to A to change B's state (basically forwarding call to B)
E.g.
A.setBTitle("");
and internally in this method, A call B.setTitle("");
Sorry about the long question, I think I am not really sure what exactly I want to ask. Hope you can understand. :P
That may work for smaller classes, but I would shudder at how you would have to main a more complex object hierarchy. Imagine if A
suddenly had several objects as fields. Do you think it would be a good idea to right a wrapper around each of them? And then think of doing so as each object becomes more complex. Sometimes doing A.getB().getC().setThingamabob()
is easier than writing A.setSomething()
which calls B.setCField()
which calls C.setThingamabob()
.
If you think an object should not be mutable, remove the setters. If a consumer of A
does not need to change B
at all, do not provide the getB()
method and instead provide something similar to A.setThingy()
, where it does not mention that whatever is being set is part of B
.
Your API contract does not necessarily mean that your classes HAVE to provide getters/setters for all of its properties. If the properties are not meant to be read/modified directly by consumers, do not provide ways of doing so.