I agree with all the answers. Getters and setters are essential.
But the point is, they are at all times necessary?
What really needs to be accessed?
It happens that it is common practice to create getters and setters for all the properties of a class. It is not reflected on the real need nor on the possible side effects of this.
Many methods are created unnecessarily, thinking perhaps that they may be necessary some day, but are never used. This only makes the code more error-prone.
And the interface?
Although setters and getters is a type of encapsulation of the attribute, the signature of the public method is part of its interface, being a type of "contract" with the other classes.
The attribute may be encapsulated, but in no way are you free to change the implementations, since any change in attribute will probably also affect the signature of some method.
And the complex objects?
For example, if my class has a list:
public class Turma {
private List<Aluno> alunos;
}
What to do? Putting one setAlunos
?
public class Turma {
private List<Aluno> alunos;
public void setAlunos(List<Aluno> alunos) {
this.alunos = alunos;
}
}
Or manage the list internally?
public class Turma {
private List<Aluno> alunos = new ArrayList<Aluno>();
public void addAluno(Aluno aluno) {
alunos.add(aluno);
}
}
There are several situations where it is better not to have the method Setter.
In the first example, the list is "exposed". It is possible that the list implementation passed by another developer does not have any method used internally implemented. For example, if our class adds students at some point, but the past list is immutable.
Immutable Objects
In scenarios where a business object is shared between several threads concurrently, setters can cause undesirable effects. Immutable objects (without setters) are much safer and efficient in this regard, as they cannot end up in an inconsistent state due to competition.
In addition, if an object is passed to various routines and services, the setters may be inadvertently called by some routine leaving the object in an inconsistent state. Suppose you have already applied all the validation rules, but before writing the database data one of the routines calls a set. Then you need to "hunt" who was responsible for the change.
One more point, is that some objects could benefit from cache information. For example, if one of the attributes is calculated from several others. But the various setters leave this implementation much more complex.
Creating an immutable object is not difficult. One way is to allow setting values through the constructor and to have no methods set. Example:
public class Turma {
private List<Aluno> alunos;
public Turma(List<Aluno> alunos) throws ListaDeProblemasException {
this.alunos = alunos;
//valida e processa alunos como bem quiser
//sabe-se que não irá mudar depois
}
public List<Aluno> getAlunos() {
return alunos;
}
}
Validation in the September?
Use setters for validation is interesting to some extent.
This can actually become a problem in cases where one attribute depends on another. Imagine, for example, that you have a method setCPF
and other method setCNPJ
. Both can only be called, respectively, if the person’s type is F
or J
. And if anyone decides to call those before these?
In addition, it becomes much more difficult to treat this type of error to, for example, display the list of errors to the user on the screen.
Completion
Getters and setters can be, yes, an illusion of encapsulation in many cases, mainly because the public methods of a class increase the coupling and the "commitment" in maintaining all those methods.
It’s not that it’s an illusion in itself, but it occurs in the minds of programmers who think encapsulamento = getter + setter
. They will later discover "strange" behaviors in the program because in fact there is nothing "hidden".
Minimal public method implementation makes code more "secure" and flexible.
In theory, a Setter not only set the value of a variable, but also treat at least the basic input value as well as validate it. Also, through a Setter you have, depending on the language, typing.
– Bruno Augusto
Related: Doubt about the responsibility of a get()
– Math
It is only a "spirit", a good practice of programming given the paradigm itself. It would be complicated if everyone could deliberately tamper with my limbs/organs. So the getter’s and Setter’s come to affirm this idea that we must "ask" to define or access something that belongs to us (objects).
– Cold
Worth reading: http://www.javaworld.com/article/2073723/core-java/why-getter-and-setter-methods-are-evil.html
– Math
@Cold, is that a "bad practice" you mean? Getter and Setter without any purpose only complicates the code, in practice I have never seen one of them that treats anything in entities or in Vos, nobody is crazy to put logic in there, in anemic domains, the rules stay in the layer of "Service". I only use them when I am "forced" by some "framework" that has bad practices.
– danilo