3 ms·
Not at all. Getters and setters are a nasty code smell that generally arises when the author does not really understand OOP. You delegate to objects (tell, don'
by RyanZAG 13y ago
Not at all. Getters and setters are a nasty code smell that generally arises when the author does not really understand OOP. You delegate to objects (tell, don't ask). Delegate to objects generally means person.goToWork() and not person.setIsAtWork(true). If your code is full of getters/setters you can probably refactor it to be far clearer.
A more non-conventional Java (but very far from crazy) is to use property accessors (person.name) instead of methods (person.getName()) for "data objects" (structs, really). Some people are very much against it as they believe it stops you being able to modify your object later, but I'd say modifying the access behavior of a struct (eg, O(1) to O(n) access) is even worse than forcing users to update their use of the object.
Anyway it's a far deeper topic than just "crazy java".
- ninjakeyboard 13y agoThanks - that's a great reply. There are lots of horrible code smells common in java like 'Impl' for names. Interesting rebuttle - nice one.
- unclebucknasty 13y ago>A more non-conventional Java (but very far from crazy) is to use property accessors (person.name) instead of methods (person.getName()) for "data objects" (structs, really). Yeah, it's a bit of a fallacy that requiring getters and setters (especially as simple pass-thrus) for simple properties is required for "good" OO (particularly that it maintains encapsulation). The bottom line is that providing both getters and setters makes the property mutable just as it would be via direct property access. Except now there's a performance penalty, as you mentioned. And renaming a property typically means renaming the getters and setters anyway lest the property name no longer makes sense internally. Any good IDE will allow you to accommodate either refactoring (property name or accessor method names) with ease. Initially, setters were also intended to allow the object to fire an event in the case that it's Observable or otherwise participating in a listener-style event system, such as that prescribed by the JavaBeans spec. But, in practice, that pattern is followed so rarely that it hardly merits forcing all of that baggage on every value object ever written.
- RyanZAG 13y agoThe performance penality I'm talking about is far more tricky than just the little bit of overhead on a method vs a property. Take this simple data object as an example: class Person { public int age; } Now a 'best practice' is to create getters and setters: class Person { private int age; public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } } This obviously makes the code uglier. This is done because maybe in the future you'd want to change the implementation of how age is stored inside the object. However, I think this is exactly where nasty performance bugs can slip in. Accessing 'age' or 'getAge()' are currently both O(1) operations with 'age' being slightly faster. However, 'age' will always be O(1) as guaranteed by the language, so using it inside a tight loop is fine. However, what happens if we modified our getAge() to be O(n) because we wanted to store age differently? eg: class Person { private List<Integer> subAges = ...; public void setAge(int age) { ... } public int getAge() { int age = 0; for (int subAge : subAges) { age += subAge; } return age; } } What we've done here is utilize our ability to change our getAge method without impacting anybody who is using our class. However, we've turned our getAge from O(1) to O(n) with absolutely no warning to anybody using our function. We've caused far more harm than simply requiring other developers to update their code - we've sabotaged the performance of all the users of all the software that uses our library. So imo the 'benefit' you get from getters/setters is more of a danger than anything. If the implementation of a library changes enough that you need to change your data access objects, you should just release a completely new API anyway as all the assumptions made by users of your library are now right out the window.