Getter and setters, also known as accessors and mutators; and predicates are very useful to attain abstractions and encapsulation in object oriented programming. In schools, when you initially learn about these, you start to use them everywhere you can. You start a class, add some private class attributes at some point and then add getters, setters and predicates for each attribute. This is not okay and you should look into the context and make a judgement.
To overcome verbosity, I will use the term GSP to refer to getter, setter and predicate in rest of the article. Similarly, GSPs will refer to plurals of these terms.
There are 4 possible cases of having or not having GSPs.
- Not having GSPs at all, allowing the direct use of all class properties.
- Having GSPs all the time. Exposing every private property via GSPs.
- Not having GSPs at all, allowing the direct use of some class properties that are required to be exposed.
- Having GSPs at approprite times and not exposing every private property.
In the above list, we will not discussing 1 and 2 much, because they options are simply studpid to follow. It is like to find an easy way out of software design, and you can’t. Our focus will be to discusss the pros and cons of 3 and 4.
Even though the benefits of having getters, setters and predicates are overwhelming, but it doesn’t mean that you should have them for every property in class. Always look out for the context. GSPs expose information about a class. The less a user class knows about a used class, the lower the coupling would be between them. There is a strong reason in making a property private and that is not letting other classes see them, and in words of Uncle Bob Martin:
There is a reason that we keep our variables private. We don’t want anyone else to depend on them.Clean Code by Robert C. Martin
Find below the benefits of having getters, setters and predicates. And remember, these are benefits of having them only when they are appropricate.
- Immutability: First and the biggest advantage of getters/setters is immutability. An extra layer of abstraction helps you in deciding the state of your object.
- Refactoring: They allow you to follow Uniform Access Principle. Are you simply returning class properties or doing some calculations to generate the return value? No one needs to know. The less one module knows about the other (especially its internal implementation), the more loosely-coupled they are. I put this as an added advantage to refactoring because you can refactor without hesitation. You can change a simple returning field to calculation and vice versa with confidence.
- Third Party Access: They are very useful if you are writing a library that will be used by third party application. They will help in making sure the communication happens as expected.
- Validation: This is connected to above two benefits, you can have validation in getter, setters right now or later on.
- Consistency: You will access a field in a consistent way.
- Agility: You don’t know what is coming next, at least sometimes. GSPs allow you to be prepared to keep the changes to the smallest scope. For example, type change of your class field.
- Polymorphism: A child class can decide differently on how to set or get a class property.
Find below some of the disadvantages of having getters, setters and predicates. These disadvantages are for the cases when they are appropriate. Because “having GSP all the time” is a superset of “having GSP appropriate times”, it denotes that these disadvantges also apply to having GSP all the times among several other that I will not go into (because again it is just stupid).
- First of all, you should know that having getters and setters for every class field is not the way to go. It breaks encapsulation and is simply a bad design. Don’t do it. That is one step away from making all data members public.
- Extra abstraction layer will consume some extra execution time. Although very low and acceptable in most cases, but it is there.