Where should main live
Published: 2022-09-01 04:01:46

This is part of a brief series on [Good Habits For Java Programmers](https://dev.to/mbrubin56/good-habits-for-new-java-programmers-1n2).

A Java program needs to have a method with the signature
`public static void main(String args[])` in some class. It serves as the entry point for your program. When you run your program, the Java runtime finds this magic entry point, calls it, and you're off to the races. You'll have to house this method in a class, because that's just how it works. The question entertained by this post is in _which_ class should the `main` method go.

In [How To Get Out Of Main And Reduce Static](https://dev.to/mbrubin56/how-to-get-out-of-main-and-reduce-static-1ddp), we moved most of our logic out of our `public void static main` method into our `Square` class and ended up with this code:
```java
public class Square {
    private float sideLength = 0.0f;

    public static void main(String args[]) {
        Square square = new Square();
        square.setSideLength(3.2f);
        System.out.println("The area of the square is " + square.getArea());
        System.out.println("The perimiter of the square is " + square.getPerimeter());
    }

    public void setSideLength(float length) {
        sideLength = length;
    }

    public float getArea() {
        return sideLength * sideLength;
    }

    public float getPerimeter() {
        return 4 * sideLength;
    }
}
```
It's a good idea to review that post. In it, I noted that we should think of `main` as just a contractual rendezvous point with the Java runtime. It's how the Java runtime finds a place to start your program, and that is its primary role. Given that, does `main` belong in `Square`? It really doesn't have anything to do with a square, the shape. If I ask you to tell me the properties of a square that you should model with a `Square` class, you'll tell me about side length and the formulas for the area and perimeter of a square and the like (maybe what the angle measurements are for a square, etc.), but you wouldn't say that they have a contractual entry point through which a Java runtime can start a Java program.

So with that in mind, it should seem off that `main` is a method of `Square`. It can be _convenient_ to put it there: in this, case it keeps your program all in one file. But _conceptually_, it's odd.

I'll pile on here. What if you enhance your program to hardcode values for other shapes (e.g. circle, triangle) and output their areas and perimeters? Would you insist on keeping your `main` in `Square`? Why `Square` and not `Circle`?

Here's a similar point. Let's say you were a reader of the enhanced program and not its author: would you know which file/class had the magic `main` method in it from class names such as `Square`, `Circle`, `Triangle`? Would you say to yourself "Oh, it has to be in `Square`. Why would it be anywhere else?". Once programs start to get a bit large -- even just a few files -- I find myself having to hunt for students' `main` implementations.

So I recommend having a `Main` class (or some class with "Main" in the name) whose sole purpose is to house the `public static main` method. Make a `Main` class and put your `public static void main` in there. Now it'll be obvious to you and to everyone where your `main` method lives. And however your program grows over time, you won't have to move it from one class to another to accommodate the growth. I need to note that this is not universal convention, although I bet not many would dislike it much: it can never really hurt, and it can help.

That also aligns nicely with the idea that `main` is just a contractual entry point. Classes should model something, and if you follow this advice, your `Main` class is then modeling that it's the entry point for your program. It advertises no more than that, but it does advertise that its purpose is to house `main` (unlike `Square`'s name). So in our example, we'd have:
```java
// In Main.java
public class Main {
    public static void main(String args[]) {
        Square square = new Square();
        square.setSideLength(3.2f);
        System.out.println("The area of the square is " + square.getArea());
        System.out.println("The perimiter of the square is " + square.getPerimeter());
    }
}

```
```java
// In Square.java
public class Square {
    private float sideLength = 0.0f;

    public void setSideLength(float length) {
        sideLength = length;
    }

    public float getArea() {
        return sideLength * sideLength;
    }

    public float getPerimeter() {
        return 4 * sideLength;
    }
}

```

## Does main still contain too much?
I'm going to get more controversial here. I think even this version has `main` doing too much. I'd prefer that `Main` call a method on _another_ class that's well named for doing the work here for creating our `Square`. I'd like `main` to have as little logic as possible: it's there to fulfill our contract with Java and nothing else. Anything else that we do that's interesting should be done in a class whose _purpose_ is to do that thing. I'm advocating keeping this contract with Java separate from everything else. I'm pretty extreme here. I'd rather see something like
```java
// In Main.java
public class Main {
    public static void main(String args[]) {
        Driver.startTheProgram();
    }
}
```
```java
// In Driver.java
public class Driver {
    public static void startTheProgram() {
        Square square = new Square();
        square.setSideLength(3.2f);
        System.out.println("The area of the square is " + square.getArea());
        System.out.println("The perimiter of the square is " + square.getPerimeter());
    }
}
```
```java
// In Square.java
public class Square {
    private float sideLength = 0.0f;

    public void setSideLength(float length) {
        sideLength = length;
    }

    public float getArea() {
        return sideLength * sideLength;
    }

    public float getPerimeter() {
        return 4 * sideLength;
    }
}
```
Now `Main` does nothing than fulfill our contract with the Java runtime, `Driver` is in charge of our logic for how to drive our program, and `Square` simply models a `Square`. If we want our program to do more, we put more in `Driver`. If we change our mind about what to do first, we either change `Driver`'s `startTheProgram` implementation or we create another class that we call from `main` to do something first, and have it call `Driver`, etc.

I have to admit this: you'll find lots of folks using `Main` classes or appreciating my point about having a separate `Main` class; you'll probably find fewer excited about my creating yet another class, such as `Driver` that `main` calls, especially for small programs.