インスタンス生成の乱用
説明(どんな問題か)
どんな状態か?
new
を使ってクラスのインスタンスを直接あちこちで生成している- どのクラスがどこで使われているか把握しにくく、依存関係が不透明
- インスタンス生成のロジックが分散しているため管理が難しい
なぜ問題か?
- 変更に弱い設計になる(新しい実装に差し替えづらい)
- ユニットテストが困難(モック差し替えしにくい)
- 同じようなオブジェクト生成ロジックがコピペされがち
- インスタンス管理がスパゲッティ化
アンチパターンのコード例
- TypeScript
- PHP
- Python
class Logger {
log(message: string) {
console.log(`[LOG]: ${message}`);
}
}
class UserService {
private logger: Logger;
constructor() {
this.logger = new Logger(); // 毎回 new!!
}
createUser(name: string) {
this.logger.log(`ユーザー作成: ${name}`);
}
}
<?php
class Logger {
public function log(string $message): void {
echo "[LOG]: {$message}\n";
}
}
class UserService {
private Logger $logger;
public function __construct() {
$this->logger = new Logger(); // 毎回 new!!
}
public function createUser(string $name): void {
$this->logger->log("ユーザー作成: {$name}");
}
}
class Logger:
def log(self, message: str):
print(f"[LOG]: {message}")
class UserService:
def __init__(self):
self.logger = Logger() # 毎回 new!!
def create_user(self, name: str):
self.logger.log(f"ユーザー作成: {name}")
問題点:
Logger
の生成がUserService
の中にべったり直書き- 他のサービスでも同様に
new Logger()
を繰り返す恐れがある - 共通ロジック(ロガー)の再利用が難しい
パターン別のリファクタリング
対応可能なデザインパターン例
パターン | 概要 | 主な解決アプローチ |
---|---|---|
Factory Method | サブクラスにインスタンスの生成を委譲 | 拡張可能な生成ロジックにする |
Abstract Factory | 関連オブジェクト群をまとめて生成 | 生成ロジックを抽象化して切り替え可能に |
Builder | 複雑な生成手順を明確にする | ステップ分離で見通しよく生成 |
Singleton | インスタンスを 1 つに制限して再利用 | グローバル状態を共有する際に有効 |