views:

597

answers:

8

When I first started programming, I wrote everything in main. But as I learned, I tried to do as little as possible in my main() methods.

But where do you decide to give the other Class/Method the responsibility to take over the program from main()? How do you do it?

I've seen many ways of doing it, like this:

class Main
{
  public static void main(String[] args)
  {
    new Main();
  }
}

and some like:

class Main {

   public static void main(String[] args) {

    GetOpt.parse(args);

    // Decide what to do based on the arguments passed
    Database.initialize();
    MyAwesomeLogicManager.initialize();
    // And main waits for all others to end or shutdown signal to kill all threads.
  }
}

What should and should not be done in main()? Or are there no silver bullets?

Thanks for the time!

A: 

I think the main method should explain, what the program does at starting up. So it may call initialzing methods, but the logic should be extracted into methods.

In your example, I would not create a Main() method, but put it into the original one.

furtelwart
+4  A: 

Whatever floats your boat, as they say. :) You should really focus on making the code simple, easy to read and efficient, using whatever tools you need to achieve this. If it warrants putting lots of code in main - do so. If you feel that objects would make things more organized - go that way.

Making a single instance of class Main and then calling the instance method Main() which does all the work is just as good as writing everything in the main method directly.

Vilx-
+5  A: 

In my opinion, the "main" of a sizable project should contain around 3 function calls:

  • Calling an Initialization function that sets up all the required settings, preferences, etc. for the application.
  • Starting up the main "controller" of the application
  • Waiting for the main controller to terminate, and then calling a Termination function that cleans up anything that needs to be cleaned up in "main" (though the controller will have taken care of most of the cleanup already).

Any sizable application will be divided into chunks of functionality, usually with some hierarchy. The main controller may have several child controllers for specific features.

Doing it this way makes it much easier to locate specific functionality, and separation-of-concerns is better.

Of course, as other replies have said, there really is no silver bullet in software development. For a short project I might put everything in main just to get things up-and-running quickly. I think also depends on the language - some options may be easier than others in particular languages.

MadKeithV
A: 

The design of your program will decide the shape of your "main".

Having a "rule" that says how your main function should be, is - IMHO - a non-sense.

Edouard A.
+2  A: 

I would say that it's not what's in your main function, but what's not. Depending on the complexity of your project, you'll want to break it down into functional sections, like "Database functions", "Display functions", "High Tea with the Vicar", etc.

It's all about readability of code. Can someone else, who has never seen your program before come across it, and get at first, a good generalised idea of what it does?

Can then then easily see where to go to dig a little deeper into the mechanism?

Is each functional section you use doing only a logical block of processes? It doesn't have to only do one thing, but it shouldn't be doing everything plus the kitchen sink.

Break down your code in a way that it's maintainable by an outside source.

Cause heavens knows, when it comes right down to it, if someone -else- can fix the bug, it's all the better =)

As a direct answer to your question, I would put the function calls to each of the major components in main, the setup, the process and the finish, so that anyone who looks at it gets a quick overview of how the program works. They can then drill down further should they need to.

Wobin
+13  A: 

Code in the main function:

  • Can't be unit-tested.
  • Can't receive dependencies by injection.
  • Can't be reused by other applications similar to the first one you write.

Therefore code in the main function:

  • Must be so simple that you're happy with functional/system tests only.
  • Must be responsible for setting the ball rolling for the dependencies used by all your other code (which is to say, main acts like an uber-factory which creates your application).
  • Should only do things which are particular to the way your app is set up (i.e. not anything which test code or the demo version will need to do exactly the same way).

In practice, this means that real apps don't have much in main. Toy apps and one-shot programs might have quite a lot in main, because you aren't planning to test or reuse them anyway.

Actually, some of what I say above is C++-specific. Java main methods of course can be called by test code or variant apps. But they still don't take objects as parameters, only command-line arguments, so the extent to which they can be isolated under test, or behave well in terms of re-use, is quite low. I guess you could pass class names for them to instantiate and use to create the rest of the app.

[Edit: someone has removed the "C++, Java" tags from this question. So: what I say above is C++ and Java specific. Other languages may treat main in a way which is less special, in which case there may be no particular reason for you to treat it specially either.]

Steve Jessop
+1  A: 

Look, the content and form of the "main" method is very language and environment dependent. In Java, every class can have a public static void main() method, so it's entirely feasible to have more than one.

But now, let's think about this via parnas's law of modularization: "every module conceals a secret, and that secret is something that can change." The "secret" of the module that is called initially is the details of interfacing the process with the operating system: things like getting the arguments and handling irregular terminations. In Python, this leads to something like this:

def main(args=None):
    #argument processing
    #construct instances of your top level objects
    #do stuff

if __name__ == "__main__":
   try:
      main(Sys.Argv)
   except: # everything
      # clean up as much as you can
   else:
      # normal cleanup, no exceptions

The point here being that you get everything from the environment you can, then call the main() function; you catch all uncaught exceptions and you do something intelligent with them before the program dies.

Charlie Martin
A: 

Remember that if someone wants to get an idea of how your program works, the first place they'll probably look is in main (at least I would). So, I don't think it's a good idea to put as little in it as possible. But I would say to put as little as is necessary to get a birds' eye view of how your program works.

Thus, I think your single biggest concern in implementing a main function should be readability.

Jason Baker