"New" is a Dirty Word

In OO programming, instantiating, delivering and utilizing object instances is pretty serious work. If you don’t think carefully about where and when to use “new”, your entire system can suffer – code reuse and refactoring become more and more difficult, and you may not even know why it’s happening. Calling “new” in the wrong place is not uncommon… but it can be disastrous.

A number of coding strategies we employ – TDD and Presenter First (http://atomicobject.com/files/PresenterFirstAgile2006.pdf), for example – lean heavily toward highly decomposed systems of objects, each object specially (and narrowly) designed to do a simple job, and not much else. We design these objects by delegating any complex behavior we encounter to subcomponents, which have been provided to us by somebody else. The need to this was driven on the ground by the need to test the higher-level object in terms of its interaction with its components.

If we’d called “new” on the subcomponents in the main component’s constructor, we couldn’t have tested the way we needed to. We made it someone else’s responsibility to give us the objects we needed. We expected to be able to change these demands at will, and get more or less objects brought in to do our work, and we didn’t expect to have to pay much for it.

Our fight for testability kept leading us down the path to ever smaller, narrow-purpose objects that could have their special behaviors isolated from their real-life circumstances (ie, the objects they use to accomplish their tasks). But as we started to delegate responsibility, the issue of object composition and delivery became monstrous. Who should create these objects was often conflicting with who could create the objects. Who has access to the components needed to build object A, and then, who needs to be composed with object A… the locations were not always consistent. We began to hate and fear “constructor chains, ” and indeed the “new” operation itself.

Unfortunately, we found the “owning” objects of these demanding components to be a little overburdened with the need to change whenever one of their “owned” objects needed something new. It became more and more difficult to keep them supplied with the materials they needed to construct and compose those other objects.

We identified that to create an object from thin air is a fairly important responsibility for a class. So if a class instantiates objects, and we’re going for classes of single responsibility, all that class can do with its objects is send them somewhere else. Which means that any class that instantiates objects in its own constructor for is own use is already doing to much and needs to be decomposed.

The quick-n-dirty method is to have a class or factory method somewhere that does all or most of the object composition for a major area (or all) of an application.
1
2
3
contact_editor_model = ContactEditorModel.new
contact_editor_view = ContactEditorView.new
ContactEditorPresenter.new(contact_editor_model, contact_editor_view)
The more elegant and helpful method is to replace the quick-n-dirty code with its metadata equivalent. In Ruby, we’ve made a tool called DIY that lets you declare object composition in a YAML file:
1
2
3
4
contact_editor_view:
contact_editor_model:
contact_editor_presenter:
  compose: contact_editor_model, contact_editor_view
And when you need to provide the model with a dialog shower, you simple update the builder code (or metadata):
1
2
3
4
5
delete_confirmation_dialog:
dialog_shower:
  compose: delete_confirmation_dialog
contact_editor_model:
  compose: dialog_shower
In addition to having a very nice mechanism to describe your composition, you:
  • isolate the composition responsibility from the rest of the code
  • do not have the opportunity to write code in your compositing area that you have no business putting there. The devil may not tempt you.
  • can easily generate documentation about the composition of your system, including tables and graphs (we’ve used a combination of WEBrick and Graphviz to create a local webapp for interactively navigating the object structure of a large .NET desktop app… it was very instructive at times.)
  • feel encouraged to decompose more and more of your code, because there is no pain associated with it now. It’s fun.
For Java and .NET we’ve used Spring and Spring.NET. Both tools have WAY too many features for us, but for what we do need, they do nicely. For C++ we’ve done the “quick-n—dirty” way which still accomplishes the isolation of composition, but is a little harder on the eyes. (We’ve discussed using a pre-compiler step to generate the compositing C++ code from metadata, to reduce programming error and provide the nice features of documentation and graphing you can get from the markup used by the other tools.

Tips In reference to system-level (architectural) objects:

  • Don’t call new() unless it’s your explicit job to do so
    • Find tools that call new() for you
  • If you build it, you cannot use it.
    • Pass it off, or notify others to come and get it.
  • Use constructor-based injection
    • An object cannot really function without its primary components.
    • Prevents dependency cycles in your design
Links