30

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++

  • 3
    Could you add a bit more context? Language? Threaded vs single thread? difference between start and the constructor? etc... – user40980 Jul 23 '13 at 15:52
  • @MichaelT I can see why you're asking, but I'm interested in the general principle behind when it's appropriate. I'm concerned that if I gave specific examples from the code base I'm working on, the answers would be too focused on the details and not on my specific questions. – Dave Hillier Jul 23 '13 at 16:33
  • 2
    @DaveHillier For example, in perl it is standard practice (and a good one) to have an init method of some sort outside of the new function - perldoc.perl.org/perlobj.html . The idioms of one language may work well there and not in other languages. – user40980 Jul 23 '13 at 16:40
  • 1
    Examples of classes with Start methods in common APIs include threads and stopwatches. – luiscubal Jul 23 '13 at 22:22
  • 1
    Count me among those who need a code sample to understand what you're actually asking. – user16764 Jul 23 '13 at 22:47
44

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.

  • 1
    Another use for a start method is when the action done also creates a new worker thread or a timer. The constructor should not do this kind of heavy lifting or generate significant side effects (like creating a new thread). – Ziv Aug 2 '13 at 21:09
50

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.

  • 16
    A good analogy. It's worth noting that Start() could correspond to either an on/off switch (like a lightswitch) which should then have a Stop(), or to a push-button (like the Print button on a copy machine) where it kicks off and then runs until done. – Bobson Jul 23 '13 at 16:07
  • 3
    +1 well said and welcome to P.SE, answers like this are a great start. – Jimmy Hoffa Jul 23 '13 at 16:13
14

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

    }
}
  • 5
    Another benefit of lazy initialization that is worth noting is that it takes very little effort to form it into a virtual proxy. Depending on the situation, this can be very useful for displaying something while waiting for a resource to load (especially useful for things like remote images). Based on the original question, I don't think this is actually what the OP was gunning for, but thought it was worth mentioning. – Dan Albert Jul 23 '13 at 19:42
  • @DanAlbert you're right it's not what I was asking for but still interesting – Dave Hillier Jul 25 '13 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.