command-line demo app I started learning from the book: head first design patterns. As I am trying out different programs in the book, I am compiling them in this one demo app. Below is the code for its driver function. Can anyone guide me with any improvements to the program (related to style, programming, formatting, how to test, is it better to have try/catch/finally or throw exceptions and stuff like that or anything else) in this driver code?

Demo Driver Code:

package com.aviralgarg;

import java.util.Scanner;

import static com.aviralgarg.strategy.Main.runDuckSimulator;

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

        try {
            demoLoop();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.err.println("Something went horribly wrong!");
        }
    }

    private static void demoLoop() {
        while (true) {
            showOptions();

            Scanner scanner = new Scanner(System.in);
            int option = scanner.nextInt();

            switch (option) {
                case 0 -&gt; System.exit(0);
                case 1 -&gt; showDesignPrinciples();
                case 2 -&gt; runDuckSimulator();
                default -&gt; System.err.println("Please select a valid option.");
            }

            showHorizontalLine();
        }
    }

    private static void showHorizontalLine() {
        System.out.println("------------------------------------------------------------------------------------");
    }

    private static void showOptions() {
        System.out.println("\nPick one of the following options:" +
                "\n\t1. Show design principles" +
                "\n\t2. Strategy pattern - Run the Duck Simulator" +
                "\n\t0. Exit");
    }

    private static void showDesignPrinciples() {
        System.out.println("Design Principles:" +
                "\n1. Identify the aspects of your application that vary and separate them from what stays the same." +
                "\n2. Program to an interface, not an implementation." +
                "\n3. Favor composition over inheritance." +
                "\n\n");
    }
}



Entire repository can be found here: https://github.com/aviral-garg/design-patterns. Any improvement in rest of those functions would be appreciated as well. Or I can just ask a separate question for that since the strategy design pattern is split into several different files and is quite abstracted away from this driver code.
main

It is not considered good practice to just catch every possible exception like this. You should always specify which exceptions are possible and should be catched. In this specific case, the try-catch-statement is not necessary at all, because you are catching all possible exceptions in demoLoop already:

public static void main(String[] args) {
    demoLoop();
}


demoLoop

Are you trusting the user with making correct inputs? If the user does enter a String instead of a number, your program will crash. You can solve this problem by using the following snippet:

private static void demoLoop() {
    Scanner scanner = new Scanner(System.in);
    showOptions();
    int option;
    while(true) {
        try {
            option = scanner.nextInt();
            if(option &gt; 2 || option &lt; 0) {
                throw new InputMismatchException();
            }
            break;
        }
        catch(InputMismatchException e) {
            System.out.println("Enter 0, 1 or 2!");
            scanner.nextLine();
        }
    }
}


(don't forget to import java.util.InputMismatchException;)

I also don't like the way how you use the switch-case-statement, but this is probably just a matter of taste. I prefer the standard way:

switch (option) {
    case 0 : 
        System.exit(0);
        break;
    case 1 : 
        showDesignPrinciples();
        break;
    case 2 : 
        runDuckSimulator();
        break;
    default : 
        System.err.println("Please select a valid option.");
}