We recently upgrade to PMD 6.0.0 and are getting several classes flagged as "Data Classes"? It argues that it breaks encapsulation and makes for brittle design (I understand that this site has a different opinion).

Let's say that our team decides to go ahead and refactor the data class, instead of ignoring the PMD rule. Unfortunately, PMD's documentation for the rule is unclear to me.

Refactoring a Data Class should focus on restoring a good data-behaviour proximity. In most cases, that means moving the operations defined on the data back into the class. In some other cases it may make sense to remove entirely the class and move the data into the former client classes.

I don't understand what "good data-behaviour proximity" is, or what "the former client classes" are. For instance, we have something along the lines of this:

public class Person {
    private String name;
    private List<String> formerNames;
    private List<Food> favoriteFoods;

    //getters and setters

How would I go about refactoring this Data Class, as PMD recommends?

I'd like to focus on what sort of refactoring would look like, rather than discussing whether the rule is a good one or not. At this time, we don't know if we want to allow this rule or exclude it.

  • I believe that “data-behavior proximity” here means “how close the definition of the data is to the definition of the behavior that uses that data.” IE, in many cases only one class needs the data, so you can just make it private to that class. Sometimes, you can refactor so that fewer classes need the data and get benefits, too: they can get what they need done by asking other objects to do the work for them.
    – gntskn
    Jul 2, 2021 at 13:04

1 Answer 1


By relocating any methods, that depend on this data, into the "data" class. For example:

out.showlist(listNameRymes(person.getName())); // Redesign it so this
person.listNameRymes(out);                     // can be done like this

But understand this is more than just moving methods around. It's a whole different way to look at problems.

When you're using the procedural mentality you want to pull the details towards you and control them in one place. Getters let you do that. But now you've mixed the details of different things together which makes them hard to tease apart.

When you use the object oriented mentality you push the details away from you. You make other things deal with them. Rather then ask for things you tell objects to do things and expect them to handle the details.

This idea has many names but my favorite one is tell, don't ask.

Now this isn't to say that Data Classes have no place. Software communicates far and wide. Sometimes it communicates across boundaries. Some boundaries prevent you from moving methods. Some are conceptual. Yet you still need to communicate. This is when Data Classes shine.

Learn when to listen to your tool and when to ignore it. It may be better at remembering to check but you'll always be better at making the judgement call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.