Javaエンジニアが知っておくべき設計パターン5選|現場で“使える”基本パターンとは?

Javaで開発していると、「あの設計どうやって実装しよう?」と悩むことがありますよね。そんなときに役立つのが設計パターン。再利用性・拡張性・保守性を高める知恵の結晶です。
この記事では、現場で本当に使われている設計パターン5選を厳選し、Javaでの実装例とともに紹介します。


設計パターンとは?簡単なおさらい

設計パターンとは、「よくある設計の課題」に対して「再利用可能な解決策」を提供する方法論です。
GoF(Gang of Four)によって紹介された23個の基本パターンが有名ですが、すべてを覚える必要はありません。

この記事では、「実務で使えるか」という観点で5つに絞って紹介します。


1. Singletonパターン(生成に関するパターン)

特徴

  • 目的:インスタンスを1つだけ生成し、それを使い回す
  • ユースケース:設定クラス、DB接続管理など

Java実装例

public class ConfigManager {
    private static ConfigManager instance = new ConfigManager();

    private ConfigManager() {
        // privateコンストラクタで外部からのnew禁止
    }

    public static ConfigManager getInstance() {
        return instance;
    }

    public void loadConfig() {
        System.out.println("設定読み込み中...");
    }
}

2. Factory Methodパターン(生成に関するパターン)

特徴

  • 目的:オブジェクトの生成処理をサブクラスに委譲
  • ユースケース:プラグインの切り替え、IFの実装差分に応じた生成

Java実装例

interface Animal {
    void speak();
}

class Dog implements Animal {
    public void speak() {
        System.out.println("ワンワン");
    }
}

class Cat implements Animal {
    public void speak() {
        System.out.println("ニャー");
    }
}

class AnimalFactory {
    public static Animal createAnimal(String type) {
        if (type.equals("dog")) return new Dog();
        if (type.equals("cat")) return new Cat();
        throw new IllegalArgumentException("不明なタイプ");
    }
}

3. Strategyパターン(振る舞いに関するパターン)

特徴

  • 目的:アルゴリズムの切り替えを柔軟にする
  • ユースケース:ソート方法や料金計算の切り替えなど

Java実装例

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("クレジットカードで" + amount + "円支払いました");
    }
}

class PayContext {
    private PaymentStrategy strategy;

    public PayContext(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void executePayment(int amount) {
        strategy.pay(amount);
    }
}

4. Observerパターン(振る舞いに関するパターン)

特徴

  • 目的:状態の変化を他のオブジェクトに通知
  • ユースケース:イベント通知、UI更新、Pub/Subシステムなど

Java実装例

interface Observer {
    void update(String message);
}

class EmailNotifier implements Observer {
    public void update(String message) {
        System.out.println("メール通知: " + message);
    }
}

class Subject {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer o) {
        observers.add(o);
    }

    public void notifyAllObservers(String msg) {
        for (Observer o : observers) {
            o.update(msg);
        }
    }
}

5. Decoratorパターン(構造に関するパターン)

特徴

  • 目的:元の機能に追加機能を「動的に」付加する
  • ユースケース:ログ付加、バリデーション追加など

Java実装例

interface Printer {
    void print();
}

class BasicPrinter implements Printer {
    public void print() {
        System.out.println("基本印刷");
    }
}

class TimestampDecorator implements Printer {
    private Printer printer;

    public TimestampDecorator(Printer printer) {
        this.printer = printer;
    }

    public void print() {
        System.out.println("印刷日時: " + new Date());
        printer.print();
    }
}

まとめ:設計パターンは「知っておくこと」自体が武器になる

今回紹介した5つのパターンは、いずれも実務でよく出てきます:

パターン名用途
Singleton設定管理、接続管理など
Factory Method実装の切り替え、柔軟な生成
Strategyアルゴリズムや処理手順の差し替え
Observerイベント連携、通知処理
Decorator既存機能に動的な追加処理

設計パターンを学ぶことで、「なぜこの設計なのか」を説明できるエンジニアになれます。
まずは自分のコードで一つずつ試してみるところから始めてみましょう!


関連記事のおすすめ

転職でキャリアを加速させたいあなたへ

「今の職場に限界を感じている」「もっと評価される場所で働きたい」そんなあなたに向けて、転職成功の実践ノウハウと退職時の不安を解消するサポート情報をまとめました。

転職・退職で迷っている方へ。不安を解消し、自信を持って次のキャリアへ踏み出しましょう。

タイトルとURLをコピーしました