JavaRush /Java Blog /Random EN /Getters/Setters. Evil. And period
Level 5

Getters/Setters. Evil. And period

Published in the Random EN group
Article by Egor Bugaenko September 19, 2014 | Posted in: Core Java Getters/Setters.  Evil.  And point - 1 This old debate was started by Allen Holub in his famous article, back in 2003, Why getter and setter methods are evil - are getters/setters an anti-pattern and should we avoid them, or is it something we're bound to have? needed in object-oriented programming. I'll add my two cents to this discussion. The gist of the text below is this: getters and setters are bad practice; those who use them have no excuse. But again, to avoid misunderstanding, I am not at all suggesting that the use of get/set should be avoided wherever possible. No. I'm saying that you didn't even let them near your code . Getters/Setters.  Evil.  And point - 2What do you think of this statement? Worthy of your attention? Have you been using the get/set pattern for 15 years and are you a respected Java architect? And you don't even want to listen to this nonsense from a stranger? Well... I understand your feelings. I felt the same way until I came across David West's book "Object Thinking" - it is the best book on object-oriented programming I have ever read. So please. Calm down and try to understand what I'm trying to explain. Subject of Controversy There are several arguments against "accessors" (another name for getters and setters) in the object-oriented world. And they are all very correct arguments. Let's take a quick look at them. Ask, Don't Tell : Allen Holub says, "Don't ask for information you need to do a job; 'ask' the entity that has that information to do the job for you." Violated Encapsulation Principle : An object can be taken apart by other objects because they are able to embed any data into the object, through setters. An object simply cannot encapsulate its own state securely enough because anyone can change that state. Implementation Details Revealed : If you can get one object from another object, then we are relying too much on the implementation details of the first object. If tomorrow it changes (for example, the result type), then we will have to change the code. All of the above justifications certainly make sense, but this misses the most important point. Basic Misconception Most programmers believe that an object is a data structure with methods. I quote the article by Bozhidar Bozhanov: Getters and Setters are not evil. But most objects for which getters and setters are created simply contain data. This misconception is the result of a huge misunderstanding! Objects don't "just store data." Objects are not data structures with methods attached. This concept of "data storage" came from object-oriented programming and procedural languages, especially C and COBOL. I will repeat again: an object is not just a collection of data elements and functions that manipulate them. An object is not a data object. What then? Ball and Dog In true object-oriented programming, objects are living beings, just like you and me. They are living organisms, with their own behavior, properties and life cycle. Can a living organism have a setter? Can you attach (“set”) a ball to a dog? Don't think. But that’s exactly what the piece of code below does:
Dog dog = new Dog();
dog.setBall(new Ball());
So how do you like it? Can you get (“get”) the ball out of the dog? Well, let's assume you can. In case she ate it and you performed surgery on her. In this case, yes, you will be able to get (“get”) the ball from the dog. This is exactly what I'm talking about:
Dog dog = new Dog();
Ball ball = dog.getBall();
Or an even more ridiculous example:
Dog dog = new Dog();
Can you imagine this in real life? Does it sound like you write every day? If yes, then you are a procedural programmer. Just admit it. Here's what David West says on page 30 of his book: The first step in transforming a successful procedural developer into a successful objective developer is a lobotomy. Do you need a lobotomy? I definitely needed it, and I got it while reading West's book "Object Thinking". Objective Thinking Start thinking like an object and you will immediately rename these methods. Here's what you might get:
Dog dog = new Dog();
dog.take(new Ball());
Ball ball = dog.give();
Now we treat the dog as a real animal that can take the ball from us and can give it back if we ask. Just in case, I note that the dog cannot return NULL. Dogs just don't know what NULL is! Objective thinking (thinking) immediately removes NULL references from your code. Getters/Setters.  Evil.  And point - 3
A Fish Called Wanda (1988) by Charles Crichton
Additionally, objective thinking will lead to the immutability of an object, such as the “weight of the dog” in our example. You would rewrite the code something like this:
Dog dog = new Dog("23kg");
int weight = dog.weight();
A dog is an unchangeable living organism that will not allow anyone outside to change its weight, or size, or name, etc. She can "tell", upon request, her weight or name. There's nothing wrong with public methods that expose queries for certain "internal" properties of an object. But these methods are not “getters” and they should never receive the “get” prefix. We don't "get" out of the dog. We don't get her name. We ask her to tell us her name. Do you see the difference? We're not even talking about semantics here. We differentiate the procedural approach to programming from the object-oriented one. In procedural programming, we work with data, manipulate it, get it, set it, and delete it if necessary. We are in charge, and data is just a passive component. A dog is nothing to us - it simply “contains data.” She doesn't have her own life. We can freely get (get) everything we need from it and put (set) any data into it. This is how C, COBOL, Pascal and other procedural languages ​​work (worked). And the situation is completely opposite in the object-oriented world. Here we treat objects as living organisms, with their own date of birth and moment of death, with their own personality and habits, if you like. We can ask the dog to give us a piece of data (for example, its weight) and it can return the information to us. But always remember that the dog is the active component. She decides what happens after the request. And that's why it's absolutely wrong for an object's methods to start with set or get. And this is not even about violating encapsulation, as many people think. This is about the fact that either you are thinking like an object or you are still writing in COBOL with Java syntax. PS . And yes, you may ask: "What about JavaBeans, JPA, JAXB and many other Java APIs that depend on get/set?" What about the built-in function in Ruby that makes it easier to create accessors? Well, what can I tell you... you're out of luck. It is much easier to remain in the primitive world of procedural COBOL than to understand and embrace the wonderful world of real objects. P.P.S. _ I forgot to say, yes, inserting dependencies via a setter is also a terrible anti-pattern. But more on that in the next post! Original article