02 May 2007

Test Smell: Confused object

Synaesthesia

Another diagnosis for a Bloated Constructor might be that the object itself is too large because it has too many responsibilities. For example,

public class Handset {
  public Handset(Network network, Camera camera, Display display, 
                DataNetwork dataNetwork, AddressBook addressBook,
                Storage storage, Tuner tuner, …) {
    // set the fields here
  }
  public void placeCallTo(DirectoryNumber number) { 
    network.openVoiceCallTo(number);
  }
  public void takePicture() { 
    Frame frame = storage.allocateNewFrame();
    camera.takePictureInto(frame);
    display.showPicture(frame);
  }
  public void showWebPage(URL url) {
    display.renderHtml(dataNetwork.retrievePage(url));
  }
  public void showAddress(SearchTerm searchTerm) {
    display.showAddress(addressBook.findAddress(searchTerm));
  } 
  public void playRadio(Frequency frequency) {
    tuner.tuneTo(frequency);
    tuner.play();
  }
  // and so on …
}

Cut up your object Like my mobile phone, this class has several unrelated responsibilities which force it to pull in many dependencies. Like my phone, the class is confusing to use so I keep pressing the wrong button, and I find that unrelated features interfere with each other. I'm prepared to put up with these compromises in my handset because I don't have enough pockets for all the devices it implements, but that doesn't apply to my code. This class should be broken up. The sort of fault lines I look for are fields that have no relationship with each other, particularly if the methods that reference them aren't used together either.

An associated smell for this kind of class is that its test suite will look confused too. The tests for its various features will have no relationship with each other, so I'll be able to make major changes in one area without touching any others. If I can break up the test class into slices that don't share anything, then the best thing might be to do just that and then slice up the object too.

No comments: