Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write main() in an OOP way?

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!

like image 200
Srikanth Avatar asked Nov 28 '08 10:11

Srikanth


2 Answers

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.]

like image 83
Steve Jessop Avatar answered Oct 01 '22 06:10

Steve Jessop


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.

like image 25
Joris Timmermans Avatar answered Oct 01 '22 06:10

Joris Timmermans