Java | ミニアプリ:メニュー選択プログラム(switch文)

Java Java
スポンサーリンク

実務風メニュー設計(Main+Service構造)

では、先ほどの Stream API メニュー を、実務風に Mainクラス+Serviceクラス構造 に整理してみます。
こうすると、プログラムが拡張しやすく、メンテナンスもしやすくなります。


1. 構造イメージ

MenuAppMain.java   ← mainメソッド+アプリ起動処理
MenuService.java   ← メニュー処理をまとめたサービスクラス
  • Main: 入力受付・ループ制御
  • Service: 実際のメニュー処理をまとめる
  • Map+Stream API で柔軟に分岐

2. MenuService.java

import java.util.Scanner;
import java.util.Map;
import java.util.Optional;

public class MenuService {
    private final Scanner scanner;
    private final Map<Integer, Runnable> menuMap;

    public MenuService(Scanner scanner) {
        this.scanner = scanner;

        // メニュー番号と処理をマッピング
        this.menuMap = Map.of(
            1, this::showProducts,
            2, this::searchProduct,
            3, this::purchase,
            0, this::exitApp
        );
    }

    // メニューを表示
    public void showMenu() {
        System.out.println("=== メニュー ===");
        System.out.println("1: 商品一覧を見る");
        System.out.println("2: 商品を検索する");
        System.out.println("3: 購入手続きへ進む");
        System.out.println("0: 終了する");
        System.out.print("番号を選んでください: ");
    }

    // 入力値に応じて処理を実行
    public boolean executeChoice(int choice) {
        Optional.ofNullable(menuMap.get(choice))
                .ifPresentOrElse(
                    Runnable::run,
                    () -> System.out.println("→ 無効な番号です。\n")
                );

        return choice != 0; // 0なら終了
    }

    // メニュー処理
    private void showProducts() {
        System.out.println("→ 商品一覧を表示します。\n");
    }

    private void searchProduct() {
        System.out.print("検索したい商品名を入力してください: ");
        String keyword = scanner.nextLine();
        System.out.println("→ 「" + keyword + "」を検索しました。\n");
    }

    private void purchase() {
        System.out.println("→ 購入手続きに進みます。\n");
    }

    private void exitApp() {
        System.out.println("→ プログラムを終了します。");
    }
}
Java

3. MenuAppMain.java

import java.util.Scanner;

public class MenuAppMain {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        MenuService service = new MenuService(scanner);

        boolean running = true;

        while (running) {
            service.showMenu();

            int choice = -1;
            try {
                choice = Integer.parseInt(scanner.nextLine());
            } catch (NumberFormatException e) {
                System.out.println("→ 数字を入力してください。\n");
                continue;
            }

            running = service.executeChoice(choice);
        }

        scanner.close();
    }
}
Java

4. この設計のメリット

特徴解説
Mainは入力・ループ制御だけメニュー処理の詳細は Service にまとめて可読性アップ
ServiceにMap+ラムダで処理を登録メニュー追加・削除が簡単
Stream API (Optional) で安全に呼び出し無効入力時の null チェック不要
拡張性が高い例えばGUIやWebに置き換えるときも、Service クラスを使い回せる

5. 発展アイデア(実務応用)

  1. ログ出力
    • 実務では System.out.println の代わりに SLF4J や Logback を使う
  2. 複数サービスの統合
    • ProductServiceUserService などに処理を分け、MenuServiceは橋渡し役だけにする
  3. ユーザー入力のバリデーション
    • try-catch + 正規表現で不正な入力を安全に弾く
  4. Unit Test しやすい設計
    • メニュー処理を Service にまとめることで、Main を起動せずに単体テストが可能

まとめ

  • Main+Service構造にすると、プログラムが読みやすく、拡張しやすくなる
  • Stream API+Map+ラムダで switch 文を置き換えると、分岐の増減が簡単
  • 実務では、こうした設計パターンがベースになります

Java
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました