「大きな泥団子」とは何か?

西山秀治 / 2025年11月28日

UX / UI のデザインに強いWebシステムの開発と、BtoB Webマーケを支援するWeb制作を提供するN’s Creates (エヌズクリエイツ) 株式会社の西山です。

ソフトウェア工学の世界には、「大きな泥団子 (Big Ball of Mud)」と呼ばれる有名なアンチパターン(悪しき設計)が存在します。

これは、明確なアーキテクチャや規律を持たず、場当たり的な修正と機能追加を繰り返した結果、内部構造が崩壊してしまったシステムを指す言葉です。残念ながら、これは机上の空論ではなく、多くの現実のプロジェクトが直面している問題でもあります。

この記事では、なぜこの「泥団子」が生まれてしまうのか、そしてPHPのコード例を元に、この状態を回避するための具体的な設計原則を紹介します。

「大きな泥団子」とは何か?

「大きな泥団子」とは、アーキテクチャ(設計構造)が崩壊し、無秩序で複雑怪奇になってしまったシステムを指します。

名前の通り、泥の塊(かたまり)のどこを掴んでも全体が崩れてくるように、コンポーネント間の境界が曖昧で、すべてが密結合している状態です。変更が非常に困難で、バグの温床となります。

なぜ「泥団子」は生まれるのか?

最初から泥団子を作ろうとするエンジニアはいません。多くは、日々の開発の中で徐々に形成されていきます。

  • 納期の圧力: 「設計は後回し!とにかく動けばいい」という判断の積み重ね。
  • 「一時的な」修正: 本来の設計を無視した「とりあえず」の修正が、いつしか恒久的なコードになる。
  • 継ぎ足し開発: リファクタリング(整理)を行わず、既存のコードに新しい機能をコピペして継ぎ足していく。
  • 経験不足: 開発者がSOLID原則や設計パターンを知らず、最も簡単な方法(一つのファイルに全部書くなど)で実装してしまう。

PHPコードで見る「泥団子」の兆候

あなたのプロジェクトに、こんなコードはありませんか?

兆候1:神クラス (God Class)

一つのクラスが何でもやりすぎる状態です。「単一責任の原則」に真っ向から違反しています。

悪い例 (God Class)

UserController が、ユーザー登録、プロフィール更新、なぜか決済処理まで担当しています。

class UserController {

    public function register($email, $password) {
        // ユーザー登録処理…
    }

    public function updateProfile($userId, $data) {
        // プロフィール更新処理…
    }

    // なぜここに決済処理が?
    public function chargeCreditCard($userId, $amount) {
        // Stripe APIを叩く処理…
        // 領収書PDFを生成する処理…
        // 決済完了メールを送る処理…
    }
}

改善例 (関心の分離)

決済処理を BillingService という別のクラスに切り出し、UserController はそれを呼び出すだけにします。

class UserController {

    // 依存性の注入(DI)
    public function __construct(private BillingService $billing) {}

    public function updateProfile($userId, $data) {
        // プロフィール更新処理…
    }

    // 決済はBillingServiceに任せる
    public function charge($userId, $amount) {
        $this->billing->charge($userId, $amount);
    }
}

class BillingService {
    public function charge($userId, $amount) {
        // Stripe APIを叩く処理…
        // 領収書PDFを生成する処理…
        // 決済完了メールを送る処理…
    }
}

兆候2:スパゲッティコード (Spaghetti Code)

処理があちこちに飛び、ロジックが追いづらい状態です。LaravelやSymfony登場前の古いPHPによく見られました。

悪い例 (1ファイルに全てを記述)

index.php が、ルーティング、DB接続、ビジネスロジック、HTML描画の全てを担当しています。

// index.php
session_start();
$db = mysqli_connect(“localhost”, “user”, “pass”, “db”);

if (isset($_GET[‘action’]) && $_GET[‘action’] == ‘save_post’) {
    // データ保存処理
    $title = $_POST[‘title’];
    mysqli_query($db, “INSERT INTO posts (title) VALUES (‘$title’)”);
    header(“Location: index.php”);
    exit;
}

// データ表示処理
$result = mysqli_query($db, “SELECT * FROM posts”);

// — HTML —
<html>
<body>
    <h1>ブログ記事</h1>
    <form action=”index.php?action=save_post” method=”POST”>
        <input type=”text” name=”title”>
        <button type=”submit”>保存</button>
    </form>
    
    <ul>
     ( … ここでPHPのwhileループが始まる … )
    </ul>
</body>
</html>

→ これを修正しようとすると、MVCフレームワーク(Laravelなど)を導入する話になり、それは「リファクタリング」ではなく「リライト(再構築)」に近くなります。

兆候3:グローバル変数の汚染

どこからでもアクセスできるグローバル変数や $_SESSION に何でも詰め込み、処理の流れを不透明にします。

悪い例 (グローバル変数への依存)

関数 calculate_total は、引数で値を受け取らず、外側にある $user_cart を直接参照しています。これではテスト(ユニットテスト)が非常に困難です。

global $user_cart;
$user_cart = [100, 50, 200];

function calculate_total() {
    global $user_cart; // 悪魔の呪文
    
    $total = 0;
    foreach ($user_cart as $price) {
        $total += $price;
    }
    return $total;
}

echo calculate_total(); // 350

改善例 (純粋な関数)

関数は「引数」としてデータを受け取り、「戻り値」として結果を返すだけにします(純粋な関数)。

$user_cart = [100, 50, 200];

// 引数で $cart を受け取る
function calculate_total(array $cart) {
    $total = 0;
    foreach ($cart as $price) {
        $total += $price;
    }
    return $total;
}

echo calculate_total($user_cart); // 350

どうすれば「泥団子」を避けられるか?

  1. フレームワークに従う: LaravelやSymfonyのようなフレームワークは、「泥団子」化を防ぐための設計(MVC、DIコンテナなど)を最初から提供しています。レールに乗ることが最善の策です。
  2. SOLID原則を意識する: 特に「S: 単一責任の原則(クラスの役割は一つだけ)」を強く意識するだけで、神クラスの発生を防げます。
  3. リファクタリングを恐れない: 「動いているコードに触るな」は間違いです。「ボーイスカウト・ルール(来た時よりも美しく)」を心がけ、機能追加のついでに少しずつコードを綺麗にしましょう。

まとめ

「大きな泥団子」は、ある日突然生まれるのではなく、日々の小さな妥協と怠慢によってゆっくりと育っていきます。

コードが複雑になってきたと感じたら、それは「泥団子」のサインかもしれません。手遅れになる前に、こまめなリファクタリングを習慣づけましょう。

UX / UI のデザインに強いWebシステムの開発と、BtoB Webマーケを支援するWeb制作を提供する
N's Creates 株式会社は、神戸三宮オフィスまで週1出社(それ以外はリモートワーク)できる「デザイナー」「エンジニア」を募集しています。

興味のある方は、カジュアル面談しますので気軽にお問い合わせください!

同じテーマの記事