Code Smell 01 - Anemic Models

Code Smell 01 - Anemic Models

Leader posted 3 min read

Your objects have no behavior.

TL;DR: Don't use objects as data structures

Problems

  • Lack of encapsulation

  • No mapping to real-world entities

  • Duplicated Code

  • Coupling

  • Writer / Reader mismatch

  • Missing behavior

Solutions

1) Find Responsibilities.

2) Protect your attributes.

3) Hide implementations.

4) Follow Tell-Don't-Ask principle

Refactorings ⚙️

https://maximilianocontieri.com/refactoring-016-build-with-the-essence

https://maximilianocontieri.com/refactoring-009-protect-public-attributes

https://maximilianocontieri.com/refactoring-001-remove-setters

Examples

  • DTOs

Context

If you let your objects become data buckets, you kill the connection between your logic and your language.

Anemic models are classes that contain only data (properties) with little or no behavior.

They're essentially glorified data structures with getters and setters.

When you create anemic models, you end up putting all the logic that should live in these objects into service classes instead duplicated the logic across multiple services.

This approach breaks object-oriented principles by separating data from the behavior that manipulates it.

You'll find yourself writing procedural code that pulls data out of objects, performs operations on it, and then pushes the results back in.

This creates tight coupling between your services and objects, making your codebase harder to maintain and evolve.

When you identify an anemic model in your code, it's a sign that you're missing opportunities for better encapsulation and more intuitive object design.

Rich domain models lead to code that's more maintainable, testable, and closer to how you think about the problem domain.

Sample Code

Wrong ❌

[Gist Url]: # (https://gist.github.com/mcsee/73f84d80f7c3e89a216dd9e40ab71bcc)

public class Song {
   String name;
   String authorName;
   String albumName;
}

[Gist Url]: # (https://gist.github.com/mcsee/78f2dd78120db843c960ed41839f29cb)

public class Song {
   private String name;
   private Artist author; // Will reference rich objects
   private Album album; // instead of primitive data types

   public String albumName() {
     return album.name() ;
}

Detection

[X] Semi-Automatic

Sophisticated linters can automate detection.

They should ignore setters and getters and count real behavior methods.

Tags ️

  • Anemic Models

Level

[X] Beginner

Why the Bijection Is Important ️

If we ask a domain expert to describe an entity he/she would hardly tell it is 'a bunch of attributes'.

The power of object-oriented programming comes from modeling real-world concepts directly in code.

When you create anemic models, you break the bijection between the domain and your code.

AI Generation

AI code generators often produce anemic models because they follow common but flawed patterns found in many codebases.

When you ask an AI to generate a basic model class, it will typically create a class with properties and getters/setters but no behavior.

This perpetuates the anemic model anti-pattern.

You need to specifically instruct AI tools to generate rich domain models with behavior, not just data holders.

Be explicit in your prompts about including relevant methods that encapsulate business logic within the model.

AI Detection

AI tools can help identify anemic models with simple instructions like "find classes with many getters/setters but few business methods" or "identify service classes that should be refactored into domain models."

Determining which behavior truly belongs in a model requires domain knowledge and design judgment that current AI tools lack.

AI can flag potential issues, but you still need to make the final decision about where behavior belongs.

Try Them!

Remember: AI Assistants make lots of mistakes

Suggested Prompt: Convert the anemic object into a rich one focusing on behavior instead of structure

Conclusion

Anemic models might seem convenient at first, but they lead to scattered logic, poor encapsulation, and maintenance headaches.

Senior developers create rich domain models focusing on their behavior.

By moving logic from services into models, you create code that's more intuitive, maintainable, and aligned with object-oriented principles.

Your objects should do things, not just store data.

Avoid anemic models. Focus always on protocol instead of data.

behavior is essential, data is accidental.

Relations ❤️

https://maximilianocontieri.com/code-smell-28-setters

https://maximilianocontieri.com/code-smell-15-missed-preconditions-1

https://maximilianocontieri.com/code-smell-210-dynamic-properties

More Information

https://en.wikipedia.org/wiki/Anemic_domain_model

https://refactoring.guru/es/smells/data-class

https://maximilianocontieri.com/nude-models-part-i-setters

https://maximilianocontieri.com/nude-models-part-ii-getters

https://maximilianocontieri.com/how-to-decouple-a-legacy-system

Also Known as

  • Data Class

Disclaimer

Code Smells are my opinion.

Credits

Photo by Stacey Vandergriff on Unsplash


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

https://maximilianocontieri.com/software-engineering-great-quotes


This article is part of the CodeSmell Series.

https://maximilianocontieri.com/how-to-find-the-stinky-parts-of-your-code

1 Comment

0 votes

More Posts

Code Smell 02 - Constants and Magic Numbers

Maxi Contieri - Nov 18, 2025

Code Smell 319 - Hardcoded Stateless Properties

Maxi Contieri - Apr 9

Code Smell 17 - Global Functions

Maxi Contieri - Feb 28

Code Smell 16 - Ripple Effect

Maxi Contieri - Feb 19

Code Smell 15 - Missed Preconditions

Maxi Contieri - Jan 30
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!