There is an old debate, started in 2003 by Allen Holub in this Why getter and setter methods are evil famous article, about whether getters/setters is an anti-pattern and should be avoided or if it is something we inevitably need in object-oriented programming. Iâll try to add my two cents to this discussion.
The gist of the following text is this: getters and setters is a terrible practice and those who use it canât be excused. Again, to avoid any misunderstanding, Iâm not saying that get/set should be avoided when possible. No. Iâm saying that you should never have them near your code.
Arrogant enough to catch your attention? Youâve been using that get/set pattern for 15 years and youâre a respected Java architect? And you donât want to hear that nonsense from a stranger? Well, I understand your feelings. I felt almost the same when I stumbled upon Object Thinking by David West, the best book about object-oriented programming Iâve read so far. So please. Calm down and try to understand while I try to explain.
Existing Arguments

There are a few arguments against âaccessorsâ (another name for getters and setters), in an object-oriented world. All of them, I think, are not strong enough. Letâs briefly go through them.
Tell, Donât Ask Allen Holub says, âDonât ask for the information you need to do the work; ask the object that has the information to do the work for you.â Martin Fowler agrees.
Violated Encapsulation Principle An object can be teared apart by other objects, since they are able to inject any new data into it, through setters. The object simply canât encapsulate its own state safely enough, since anyone can alter it.
Exposed Implementation Details If we can get an object out of another object, we are relying too much on the first objectâs implementation details. If tomorrow it will change, say, the type of that result, we have to change our code as well.
All these justifications are reasonable, but they are missing the main point.
Fundamental Disbelief
Most programmers believe that an object is a data structure with methods. Iâm quoting Getters and Setters Are Not Evil, an article by Bozhidar Bozhanov:
But the majority of objects for which people generate getters and setters are simple data holders.
This misconception is the consequence of a huge misunderstanding! Objects are not âsimple data holders.â Objects are not data structures with attached methods. This âdata holderâ concept came to object-oriented programming from procedural languages, especially C and COBOL. Iâll say it again: an object is not a set of data elements and functions that manipulate them. An object is not a data entity.
What is it then?
A Ball and A Dog
In true object-oriented programming, objects are living creatures, like you and me. They are living organisms, with their own behavior, properties and a life cycle.
Can a living organism have a setter? Can you âsetâ a ball to a dog? Not really. But that is exactly what the following piece of software is doing:
Dog dog = new Dog();
dog.setBall(new Ball());
How does that sound?
Can you get a ball from a dog? Well, you probably can, if she ate it and youâre doing surgery. In that case, yes, we can âgetâ a ball from a dog. This is what Iâm talking about:
Dog dog = new Dog();
Ball ball = dog.getBall();
Or an even more ridiculous example:
Dog dog = new Dog();
dog.setWeight("23kg");
Can you imagine this transaction in the real world?
Does it look similar to what youâre writing every day? If yes, then youâre a procedural programmer. Admit it. And this is what David West has to say about it, on page 30 of his book:
Step one in the transformation of a successful procedural developer into a successful object developer is a lobotomy.
Do you need a lobotomy? Well, I definitely needed one and received it, while reading Westâs Object Thinking.
Object Thinking
Start thinking like an object and you will immediately rename those methods. This is what you will probably get:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
Now, weâre treating the dog as a real animal, who can take a ball from us and can give it back, when we ask. Worth mentioning is that the dog canât give NULL back. Dogs simply donât know what NULL is. Object thinking immediately eliminates NULL references from your code.
Besides that, object thinking will lead to object immutability, like in the âweight of the dogâ example. You would re-write that like this instead:
Dog dog = new Dog("23kg");
int weight = dog.weight();
The dog is an immutable living organism, which doesnât allow anyone from the outside to change her weight, or size, or name, etc. She can tell, on request, her weight or name. There is nothing wrong with public methods that demonstrate requests for certain âinsidesâ of an object. But these methods are not âgettersâ and they should never have the âgetâ prefix. Weâre not âgettingâ anything from the dog. Weâre not getting her name. Weâre asking her to tell us her name. See the difference?
Weâre not talking semantics here, either. We are differentiating the procedural programming mindset from an object-oriented one. In procedural programming, weâre working with data, manipulating them, getting, setting, and deleting when necessary. Weâre in charge, and the data is just a passive component. The dog is nothing to usâitâs just a âdata holder.â It doesnât have its own life. We are free to get whatever is necessary from it and set any data into it. This is how C, COBOL, Pascal and many other procedural languages work(ed).
On the contrary, in a true object-oriented world, we treat objects like living organisms, with their own date of birth and a moment of deathâwith their own identity and habits, if you wish. We can ask a dog to give us some piece of data (for example, her weight), and she may return us that information. But we always remember that the dog is an active component. She decides what will happen after our request.
Thatâs why, it is conceptually incorrect to have any methods starting with set or get in an object. And itâs not about breaking encapsulation, like many people argue. It is whether youâre thinking like an object or youâre still writing COBOL in Java syntax.
PS. Yes, you may ask,âwhat about JavaBeans, JPA, JAXB, and many other Java API-s that rely on the get/set notation? What about Rubyâs built-in feature that simplifies the creation of accessors? Well, all of that is our misfortune. It is much easier to stay in a primitive world of procedural COBOL than to truly understand and appreciate the beautiful world of true objects.
PPS. Forgot to say, yes, dependency injection via setters is also a terrible anti-pattern. About it, in one of the next posts.
PPPS. Here is what Iâm suggesting to use instead of getters: printers.
Getters-and-setters is ...
— Yegor Bugayenko (@yegor256) May 3, 2020
