TechCraft – エンジニアのためのスキルアップメモ

エンジニアのスキルアップを少しでも加速する技術ブログ

GoFとは? デザインパターンの基礎 第1回

GoFGang of Four)とは?ソフトウェア設計を支えるデザインパターンの基礎

1. はじめに

ソフトウェア開発において、「保守性が高く、再利用しやすい設計」 は重要なテーマです。
しかし、開発者が独自に設計を考えると、類似した問題に対して異なる解決策が生まれ、結果としてコードの一貫性が失われる ことがあります。

そこで役立つのが、GoFGang of Four が提唱したデザインパターン です。
GoFデザインパターンは、オブジェクト指向プログラミング(OOP)における「設計のベストプラクティス」 として、現在も多くの開発者に利用されています。

本記事では、まず GoFとは何か を詳しく解説し、
続いて 代表的なデザインパターン「Singleton」 の実装を複数のプログラミング言語で紹介します。


2. GoFGang of Four)とは?

2.1. GoFの概要

GoFGang of Four は、1994年に出版された書籍
「Design Patterns: Elements of Reusable Object-Oriented Software」 の著者である4人のエンジニアの総称です。

著者名 主な功績
Erich Gamma JUnitの開発者、Eclipseの設計にも貢献
Richard Helm IBMのソフトウェアエンジニア
Ralph Johnson オブジェクト指向設計の専門家
John Vlissides デザインパターンの理論的基礎を確立

この書籍では、オブジェクト指向設計における23のデザインパターン を定義しており、
現在もソフトウェア設計の重要な指針として活用されています。


2.2. GoFデザインパターンの分類

GoFは、デザインパターンを以下の3つのカテゴリに分類しています。

カテゴリ 概要 代表的なパターン
生成パターン(Creational Patterns) オブジェクトの生成を最適化する Singleton, Factory Method, Builder, Prototype
構造パターン(Structural Patterns) クラスやオブジェクトの構造を最適化 Adapter, Bridge, Decorator, Composite, Facade
振る舞いパターン(Behavioral Patterns) オブジェクト間の動作を管理 Observer, Strategy, Template Method, Command

この中でも、最も基本的で広く使われるパターンの1つが Singleton(シングルトン) です。
次章では、Singletonパターンの実装を複数の言語で解説 します。


Singletonパターン:唯一のインスタンスを保証するデザインパターン

3. Singletonパターンとは?

3.1. Singletonの概要

Singleton(シングルトン)パターン は、
「あるクラスのインスタンスを1つだけ生成し、それをグローバルにアクセスできるようにする」デザインパターンです。

メリット - 唯一のインスタンスを保証 できる - グローバルアクセスを提供 できる - メモリ使用量を削減 し、不要なインスタンス生成を防ぐ

デメリット - 依存関係が強くなりやすいグローバル変数のような影響を持つ) - マルチスレッド環境での競合(適切な排他制御が必要)


4. 各言語でのSingletonパターンの実装

Singletonパターンは、言語によって異なる方法で実装されます。
ここでは、JavaPythonC++、Go での実装を紹介します。


4.1. Javaでの実装(スレッドセーフ対応版)

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}  // private コンストラクタ

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

volatile 修飾子と synchronized を使用し、スレッドセーフを確保


4.2. Pythonでの実装(クラス変数を利用)

class Singleton:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

# インスタンスの取得
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2)  # True(同じインスタンス)

__new__() メソッドをオーバーライドし、唯一のインスタンスを保証


4.3. C++での実装(スレッドセーフ対応版)

#include <iostream>
#include <mutex>

class Singleton {
private:
    static Singleton* instance;
    static std::mutex mutex;
    
    Singleton() {}

public:
    static Singleton* getInstance() {
        std::lock_guard<std::mutex> lock(mutex);
        if (instance == nullptr) {
            instance = new Singleton();
        }
        return instance;
    }
};

// 静的メンバ変数の定義
Singleton* Singleton::instance = nullptr;
std::mutex Singleton::mutex;

int main() {
    Singleton* s1 = Singleton::getInstance();
    Singleton* s2 = Singleton::getInstance();
    std::cout << (s1 == s2) << std::endl;  // 1(同じインスタンス)
}

std::mutex を使用し、スレッドセーフなSingletonを実装


4.4. Goでの実装(sync.Onceを活用)

package main

import (
    "fmt"
    "sync"
)

type Singleton struct{}

var instance *Singleton
var once sync.Once

func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{}
    })
    return instance
}

func main() {
    s1 := GetInstance()
    s2 := GetInstance()
    fmt.Println(s1 == s2) // true(同じインスタンス)
}

sync.Once を使用し、スレッドセーフなSingletonを実装


5. まとめ

項目 内容
GoFとは? 4人のエンジニアが提唱した23のデザインパターン
分類 生成、構造、振る舞いの3つに分類
Singletonの目的 唯一のインスタンスを保証し、メモリ使用を最適化
実装言語 Java, Python, C++, Go での実装を紹介

Singletonパターンは、多くのアプリケーションで使用される重要なデザインパターンです。
しかし、適用する際は「グローバル依存」や「スレッドセーフの確保」に注意する必要 があります。

📌 次回の記事:「GoFの他のデザインパターン(Factory, Builder)」もお楽しみに!

参考資料

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Java言語で学ぶデザインパターン入門第3版 [ 結城 浩 ]
価格:4,290円(税込、送料無料) (2025/3/7時点)


バランスよく書かれている。


網羅的に書かれています。骨太。


C++デザインパターン。少し高難度。