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 | 既存機能に動的な追加処理 |
設計パターンを学ぶことで、「なぜこの設計なのか」を説明できるエンジニアになれます。
まずは自分のコードで一つずつ試してみるところから始めてみましょう!
関連記事のおすすめ
転職でキャリアを加速させたいあなたへ
「今の職場に限界を感じている」「もっと評価される場所で働きたい」そんなあなたに向けて、転職成功の実践ノウハウと退職時の不安を解消するサポート情報をまとめました。
- ▶ キャリアを加速させるハイクラス転職の戦略
- ▶ 40代以上でも安心。経験を活かせる「エージェント」活用法
- ▶ ITエンジニア特化型「TechClipsエージェント」のリアルな評価
- ▶ 円満退職を実現するための法律サポートもチェック
転職・退職で迷っている方へ。不安を解消し、自信を持って次のキャリアへ踏み出しましょう。