TypeScript上級

上級 TypeScriptで学ぶデザインパターン|アンチパターン編

導入

デザインパターンは、ソフトウェア開発における課題を解決するための再利用可能なソリューションを提供します。しかし、実際の開発現場では、デザインパターンを誤って適用することが多く、その結果としてアンチパターンが生まれることがあります。このアンチパターン編では、特にTypeScriptを用いた実務でよく見られる失敗例を取り上げ、どのように改善できるかを考察します。

教科書レベルの解説(デザインパターン)

重要な概念の整理

デザインパターンには多くの種類があり、各パターンは特定の問題に対する解決策を提供します。例えば、シングルトンパターンは、クラスのインスタンスを一つだけに制限し、グローバルなアクセスポイントを提供するために使用されます。しかし、シングルトンを誤用すると、テストが困難になったり、依存性が強くなったりすることがあります。このように、デザインパターンを理解することは重要ですが、その適用方法にも注意が必要です。

コード例(TypeScript)


class Database {
    private static instance: Database;

    private constructor() {
        // データベース接続の初期化
    }

    public static getInstance(): Database {
        if (!Database.instance) {
            Database.instance = new Database();
        }
        return Database.instance;
    }

    public query(sql: string) {
        // SQLクエリの実行
    }
}

// 使用例
const db1 = Database.getInstance();
const db2 = Database.getInstance();

console.log(db1 === db2); // true

コードの行ごとの解説

  1. class Database { – データベースを表すクラスを定義します。
  2. private static instance: Database; – シングルトンインスタンスを保持する静的プロパティです。
  3. private constructor() { – プライベートコンストラクタにより、外部からのインスタンス生成を防ぎます。
  4. public static getInstance(): Database { – インスタンス取得メソッドを定義します。
  5. if (!Database.instance) { – まだインスタンスが存在しない場合、新たに生成します。
  6. return Database.instance; – 既存のインスタンスを返します。
  7. public query(sql: string) { – SQLクエリを実行するメソッドを定義します。

アンチパターン編

シングルトンパターンは便利ですが、実際にはいくつかのアンチパターンを引き起こす可能性があります。一つは、グローバルな状態を持つことにより、テストが難しくなる点です。例えば、テスト中にデータベースの状態が変わってしまうと、他のテストに影響を与える可能性があります。また、シングルトンを使用することで、依存性が強くなり、コードの再利用性が低下することもあります。

この問題を解決するためには、依存性注入を利用することが効果的です。具体的には、クラスのコンストラクタでデータベースインスタンスを受け取るようにし、必要なときにそれを使用する方法です。これにより、テストの際にモックを利用できるようになります。

まとめ

  • デザインパターンは強力なツールですが、誤用するとアンチパターンを生む。
  • シングルトンパターンは、特に依存性を強め、テストを難しくする要因となる。
  • 依存性注入を用いることで、シングルトンの問題を回避し、テスト可能なコードを実現できる。