Rule 7: Don’t Use Any Classes with More Than Two Instance Variables 

From the series about the rules of thumb, presented at chapter Object Calisthenics by Jeff Bay in The ThoughtWorks Anthology book from the Pragmatic Programmers (click here to see the the previous rules).

The rule

Most classes should simply be responsible for handling a single state variable, but a few will require two. Adding a new instance variable to a class immediately decreases the cohesion of that class. In general, while programming under these rules, you’ll find that there are two kinds of classes, those that maintain the state of a single instance variable and those that coordinate two separate variables. In general, don’t mix the two kinds of responsibilities. 

Now, go back and read the rule number three again. You probably notice that there are few cases where a cohesive single job description can be created for a class with many instance variables.


Example:

    String first;
    String middle;
    String last;
}

The previous code could be decomposed into two classes like this:

class Name {
    Surname family;
    GivenNames given;
}

class Surname {
    String family;
}

class GivenNames {
    List names;
}

Note that in thinking about how to do the decomposition, the opportunity to separate the concerns of a family name (used for many legal entity restrictions) could be separated from an essentially different kind of name. The GivenName object here contains a list of names, allowing the new model to absorb people with first, middle, and other given names. Frequently, the decomposition of instance variables leads to an understanding of commonality of several related instance variables. Sometimes several related instance variables actually have a related life in a first-class collection.

Decomposing objects from a set of attributes into a hierarchy of collaborating objects leads much more directly to an effective object model. The recursive application of this rule has led to a very quick decomposition of complex large objects into much simpler models. Behavior naturally follows the instance variables into the appropriate place. If you get stuck, work downward by splitting objects into related halves or upward by picking any two instance variables and making an object out of them.