3

In Java main methods often do little more than parsing the command line arguments and initializing an object that then takes over, for example:

public class FooServer {
    // ...

    public static void main(String[] args) {
        // Process arguments ...
        FooServer server = new FooServer(...);
        // Initialize server ...
        server.start();
    }
}

I have seen that some software extracts this main method into a separate "main" class (often ending in Launcher or Main):

public class FooServer {
    // ...
}

public class FooServerLauncher {
    public static void main(String[] args) {
            // Process arguments ...
            FooServer server = new FooServer(...);
            // Initialize server ...
            server.start();
        }
}

The "main" class is closely coupled to the other class, so I suppose the "main" class is separate so that it doesn't pollute the interface of the other class.

I discussed the question with a co-worker and the person was of the opinion that contemporary object-oriented programmers chop up classes into too many small separate classes to pretend that everything is interchangeable while it's not. The person argued that this is a good example of the issue as the sole purpose of the main method is to start an object from the command line and thus is in fact part of its interface.

Are there other objective arguments for against separating the main method into its own class?

4

The pattern you mentioned isn't necessarily the pattern used in all programs. For example, if I want to make a program that reads messages, processes them, and sends output somewhere, I might have a main structure that's more like this:

public static void main(String[] args)
{
    Reader reader = new Reader(args[0]);
    Writer writer = new Writer(args[1]);
    Processor processor = new Processor(args[2]);
    reader.start();
    writer.start();
    processor.start();
    ...
}

The gist here being that the thing that is launching parts of my application is not solely using one class, like in your examples. Here I would likely put the main function into a MyProgramLauncher class, because it's not directly tied to any single class, and we could potentially be adding more classes in the future(initializing logging, database connection, graphics engine, etc)

main is also a logical place to check for all of the preconditions of running your program. Eg. If you can't connect to your database, you might want to fail early and tell the user to check internet connection settings and try again.

If I have a main method like your FooServerLauncher, then I would put it in FooServer. So long as there's one main method, and it references nothing other than FooServer, then it belongs in the FooServer file. Alternatively, if you have multiple main files that utilize FooServer, then they need to be in their own Launcher style classes, so that the functionality of each 'executable' of your system remains separate.

Analyzing it with typical design metrics(when compared to having main in FooServer):

  • Readability - If anything is reduced, because the thing doing the execution and the thing being executed are separate. And in a very literal sense you have to read two different files to understand what's going on.

  • Modularity - Increased, but I would say this is following the dogma of 'modularity' to a fault.

  • Maintainability - Is also reduced for similar reasons to readability. While maintaining FooServer you likely need to alter FooServerLauncher. I would argue it's much less likely to alter FooServer and forget to update main as needed if they're in the same file. Having the separate files introduces 'out of sight, out of mind'.

  • Coupling - High, because it's 100% dependent on the implementation of FooServer. In your example, main has initialization steps and starts FooServer, which depending on your preferences may be too much coupling.

  • Cohesion - I would say low, for the same reason we have high coupling. If everything in main exists to do something tied to FooServer, then the logical place to put main is in FooServer.

For a couple of these I think you could argue they stay the same, but I'm not quickly coming up with ways in which they're improved. So, all things considered, having main in a separate file seems to be equal-to or less-than having it in the same file.

1

In Java, almost everything is an object, so main() must has to be declared somewhere obviously. Its concern is distinct from the rest of our class(which defines some data and behaviour that we are trying to encapsulate), which is getting the program ready to execute the whole thing.

In my own opinion main should not be pushed with the other data and behavior of a class. The main method's concern is with running our program. It will return to logic necessary that is declared inside of it's body. With that being said I would go ahead and keep it away from any other class and/or logic in your program.

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