Code Smell 01 - Anemic Models
8 July, 2022
9
9
0
Contributors
TL;DR: Don't use objects as data structures
The protocol is empty (with setters/getters).
If we ask a domain expert to describe an entity they would hardly tell it is 'a bunch of attributes'.
Problems
Solutions
1) Find Responsibilities.
2) Protect your attributes.
3) Hide implementations.
4) Delegate
Examples
- DTOs
Sample Code
Wrong
class Window:
def __init__(self):
self.height = None
self.width = None
def getHeight(self):
return self.height
def setHeight(self, height):
self.height = height
def getWidth(self):
return self.width
def setWidth(self, width):
self.width = width
Right
class GraphicWindow:
def area(self):
# implementation
return
def open(self):
# implementation
return
def isOpen(self):
# implementation
return
Detection
Sophisticated linters can automate detection. They should ignore setters and getters and count real behavior methods.
Also Known as
- Data Class
Tags
- Anemic
- OOP as Data
- Encapsulation
- Setters/Getters
- Mutability
Conclusion
Avoid anemic models. Focus always on protocol instead of data. Behaviour is essential, data is accidental.
Relations
https://maximilianocontieri.com/code-smell-28-setters
https://maximilianocontieri.com/code-smell-15-missed-preconditions-1
More info
- Wikipedia
- Refactoring Guru
- Nude Models — Part I : Setters
- Nude Models — Part II : Getters
- How to Decouple a Legacy System
Object-oriented programming increases the value of these metrics by managing this complexity. The most effective tool available for dealing with complexity is abstraction. Many types of abstraction can be used, but encapsulation is the main form of abstraction by which complexity is managed in object-oriented programming.
Rebecca Wirfs-Brock
Credits
Photo by Stacey Vandergriff on Unsplash
This article is part of the CodeSmell Series.