Question

I'm currently working on a code base that has many classes that implement a Start method. This seems like two-phase construction to me, which I had always considered a bad practice. I can't tell the difference between this and a constructor.

When is it appropriate to use a start method instead of normal object construction?

When should I prefer to use the constructor?

Edit: I don't think it is that relevant but the programming language is C#, it could equally apply to Java or C++

Was it helpful?

Solution

A Start() method (like Run(), Execute() or anything similar) is appropriate when the cost of constructing the object is low, but the cost of using it is high. For example: A class which encapsulates a best-path-optimization algorithm. It's trivial to set it up with a set of parameters (X squares by Y squares, with suchandsuch evaluation method), but it may take a while to execute. If you want to create 20 of these objects, you may want to delay execution until all of them have been created - this lets you parallelize them easier, for example.

Alternatively, it could be useful when you don't know when the object is going to be needed to start - perhaps because it's based on user input, or logic which selects from a list of possibilities.

This assumes, of course, that Start() is the useful method on the object, and not an equivalent to an Initialize() method. If it is just an extra way to set more parameters, it shouldn't exist.

OTHER TIPS

Code Complete (and many other software engineering resources) emphasizes matching your classes to real world objects. I believe the fundamental reason for this is that it makes it more likely that you have a true grasp of what it is that you're implementing, rather than hacking away at an intangible idea.

If you're a subscriber to this theory, I don't see anything wrong with adding a Start() method to any class that should, were it a real object, also have a resting state. If it doesn't make any sense for your object to exist while not running (or doesn't make any sense for your object to be running at all), then I would say it is bad practice.

You may use lazy initialization.

In computer programming, lazy initialization is the tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed.

That way you avoid temporal-coupling, meaning the consumer of your class has to call certain methods in certain order. Having to call start() first is a way of having to know how the class works internally, which is bad because you may change that in the future.

Delay the expensive initialization until it's first needed..

Example:

public class FooClass{

    private ExpensiveResource resource;
    private CheapResource cheap;

    public  FooClass(String someParameter){
        // constructor: initialize CheapResource cheap 
            // but NOT ExpensiveResource resource
    }

    public ExpensiveResource getExpensiveResource(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource
    }

    public String getExpensiveResourceName(){
        if (resource == null) {
            this.initializeExpensiveResource();     
        }
        return this.resource.getName();
    }   

    public CheapResource getCheapResource(){
        return this.cheap;
    }

    private initializeExpensiveResource(){
        // do expensive initialization of field "resource"
    }

}

public class Test{
    public static void main (String args[]){

        FooClass foo = new FooClass("some string");
        CheapResource cr = foo.getCheapResource();
        String s = foo.getExpensiveResourceName(); 
          // just now is the expensive resource initialized

    }
}
Licensed under: CC-BY-SA with attribution
scroll top