How to dissolve too big Entities

The problem

How to solve situation when your Entity is getting too big and there are clearly certain subsets of attributes inside it.

Good heuristics suggest that class should not contain more than 6 attributes. However I have found that in practice it is usually not easy to follow this suggestion.

Lets say we have following class:

class Account {
  private String homeCity;
  private String homeStreet;
  private String homeCountry;
  private String workCity;
  private String workStreet;
  private String workCountry;
  private String userName;
  ...
  private String password;
}

I think there are 3 main options:

Option 1

Move subset of attributes (and related behavior) into another class and fully encapsulate access to its instance

class Account {
  private Address homeAddress;
  private Address workAddress;
  private userName;
  ...

  public String getHomeCity() {
    return homeAddress.getCity();
  }
  public String getWorkStreet() {
    return workAddress.getStreet();
  }
  ...
}

class Address {
  private Sting city;
  private String street;
  private String country;
}

Option 2

Move subset of attributes into another class and expose this instance to client code

class Account {
  private Address homeAddress;
  ...

  public String getHomeAddress() {
    return homeAddress;
  }
  ...
}

and client code would look like this:

Account account = ...
String homeStreet = account.getHomeAddress().getStreet();

Option 3

Finally the easiest option of all - leave as is

Choosing the best option

Before discussing the benefits/drawback of each option there is one important thing that needs to be taken under account - namely type of containment. One way how to differentiate between strong vs weak containment is by analyzing the type of extracted class. If extracted class is a Value Object then there is always a strong containment as Value Objects don't have lifecycle of their own. On the other hand if extracted class is another Entity then there is a weak containment.

In case of weak containment or Entity-Entity relationship I think that options 1 and 2 are the main ones to consider because it is likely not desirable and necessary to hide the existence of other Entity.

If we have Entity which contains a Value Object are even multiple Value Objects then finding the best solution is not that straightforward. I think there are two main reasons why extracting Value Objects could be considered: first better understandability hence better extendability in the future and secondly potential reuse (especially if inside the same system). If we already know that in some other parts of the same system we are going to need same set of attributes again (e.g as an input values for some algorithm) then we should probably opt for option 1 or 2. Otherwise unless we can extract also significant amount of behavior besides just accessors/mutators I would likely keep things as they are and go for option 3.

About option 1 vs option 2 I think if call chains get longer than 2 levels I would start worrying about encapsulation.

Same thing described with UML:

BTW I have started my own public blog which so far contains some improved writings that have previously been posted here.

Labels

design design Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.