/ microoop

µObjects: When to instantiate

In object oriented programming we need to create objects. It's kinda how things get done.
Here's a high level question for you - When do we instantiate an object?
Pull up a few source files - Where do you see object creation happening? Is it scattered through the file? No real organization around when it happens?

I always did it when I needed it - which is why interfaces never made sense.

With µObjects; there's only a couple places to create an object.

  • Returning from a builder method
  • In dependency constructor

That's it. If I see object instantiation outside of these two; it's a code smell. It might survive until I see a better solution - but it is a smell. I add an apology to the code; make a mental note about it - and continue work. If I can't see a solution; I'm not going to force in the wrong one.

Post Done. Thanks for reading.

... ... I've been informed I should cover both those points in a little more detail.

Builder Method

I'd like to say a few sources that talk about having builder methods vs manipulator methods... but I'm lazy and google wasn't giving me anything quickly. I'm certain I've seen the builder concept in a few books; but the most recent; and the one that really sticks is Yegor's Elegant Objects. Builder methods (not the Builder pattern) are methods that return something. They don't use the object they built; theynew it up and give it out.
One element of a proper builder method is that it can return an object in two ways. The most basic; is to create a new object and return it. If the class interacts with the object it creates; then the class is tightly coupled to that object and maintainability suffers. The class creating an object can't interact with it; as that's a concrete instance being interacted with. This tight coupling kills testability. If you get away with it for a while - you're setting a pattern and a practice for yourself that will hurt the code base - you're doing it wrong.
If your builder method doesn't return the object as soon as is technically possible from when it's instantiated - you're doing it wrong.

Remember; Methods are one line

Strive for this and your builder methods will be fantastic.
As an aside here - builder methods should be named nouns; for the thing they return. Never put get on the method.

That's the most direct way for a builder method to have an object to return. The next way is through delegation. If you're holding an object; you won't return that object. You hold it; you keep it. There's some conflicting views on this - but I don't care if the name of the method doesn't have a get; if you're returning a reference held - it's a getter. Getters are always evil; Don't do it.
Right - Delegation: You hold a reference - you can ask that for an object to return.
If a friend asks for my money; I don't have cash crumbled up in my pocket... ... Let's pretend I don't have cash crumpled in my pocket. I don't 'have cash', I have a wallet.

public class Me : IMe{
    private IWallet _wallet;
}

If I want to give my money to my friend; I'll ask my wallet for it.

public class Me : IMe{
    private IWallet _wallet;
    ...
    public ICash Money(){
        return _wallet.Cash();
    }
}

My wallet and I get along pretty well; so it rarely throws an OutOfBoundsException anymore.
With this; I'm returning something someone else is giving me. I'm delegating to my wallet to get the money.
I don't want to give out my wallet... I don't know what anyone would do with my wallet - I'm going to protect the reference.

If you're wondering about how the wallet will be returning cash since it likely holds cash - You're right. It'll need to create a new object to return or continue to delegate. When I access my wallet; I don't care. Somewhere something going to return a newly instantiated object; and back up the stack we go.

Dependency Constructor

I expect this be a little new - I hadn't heard about the concept before. I started with it on some Android Proof of Concept stuff to be able to effectively test an Activity. I put my thoughts about it into a post Double Constructor. I called it double constructor; because in the simplest of cases (which mine were) there are two constructors.
At the time; the second seemed like it was only for test - but that's no longer the case. This is how to do dependency injection. This is how to follow best practices for creating immutable objects. This is how to create a highly maintainable object that changes for a single reason.
A Depdendency Constructor is a constructor that instantiates the classes dependencies. My 'Double Constructor' post gets some details wrong - It's evolved since it was written in March 2017.
One of the driving factors for the evolution into Dependency Constructors is the Front-BookEnd. In Android; this is the Activity. For a REST API this might be the controller. These are system invoked methods that tend to be empty constructors.
These MUST have an empty constructor. Which leaves very little place for objects to be instantiated AND, most importantly, decoupled.
It's not possible to have a single constructor in an Android Activity and have constructor time dependencies while remaining testable... Ignoring hacks that violate many other practices on the dependent classes.
What I found was that I could create a constructor that took in the classes I needed and just new them up in the empty constructor.

class MyActivity extends Activity{
  MyActivity(){
    this(new Thingy(), new OtherThingy());
  }
  MyActivity(final Thing thing, final OtherThing other){
    ...
  }
}

This gives the system a high level of testability. While there's still a huge aspect of "no logic in the book end" - It drove home a lot of how to manage dependencies.

I did this with the Controllers in a REST API. I didn't go all the way; unfortunately. The Controller has a Russian Nested Doll of a this constructor.

public MyController : ApiController{
    public MyController() : 
    this(new DataGuy(
            new NeatThing(
                new HttpStuff())), 
                new MoreThings(
                    new OtherThings(
                        new Finally()))){}
    public MyController(IDataGuy dataGuy){...}
}

We get this MASSIVE and ungodly mess. I hate this, so very very much. Why does the controller need to know about the details of a class 4 levels down? The answer is that it doesn't.
Changing this to follow the dependency cosntructor changes the code to

public MyController : ApiController{
    public MyController() : this(new DataGuy(){}
    public MyController(IDataGuy dataGuy){...}
}

which is vastly cleaner code. The highest level of our app doesn't have coupling to the lowest level. This was horrible code to look at. Took me a few extra months to finally start shoving the 'new' all the way down. I thought it at the time - just didn't force it.
I understand now it's far better code when using Dependency Constructors. Classes know what they need. If they need something new; THEY CHANGE IT. I don't need to change my controller because some class three levels down uses a different implementation... Single Responsibility. The Controller in the first case has too many reasons to change. It LITERALLY knows about everything.

Summary

The only ways an object should be instantiated is through a method that immediately returns it or in a Dependency Constructor.
We do this to confine and control the instantiation of new objects. Improving our testability and maintainability.

Quinn Gil

Code Crafter beating the drum of Development Best Practices. Extreme Programming and Object Oriented Design.

Read More