TypeScript中級

中級 TypeScriptで学ぶオブジェクト指向設計|アンチパターン編

導入

オブジェクト指向設計は、ソフトウェア開発における重要なアプローチの一つであり、特に大規模なシステムにおいてその真価を発揮します。しかし、実際の開発現場では、オブジェクト指向の原則を誤解し、アンチパターンに陥ることが少なくありません。この記事では、TypeScriptを用いて、よく見られるアンチパターンとその改善策について具体的なシチュエーションを通じて解説します。

教科書レベルの解説(オブジェクト指向設計)

重要な概念の整理

オブジェクト指向設計は、カプセル化、継承、ポリモーフィズムといった基本的な概念から成り立っています。これらの原則を適切に利用することで、コードの再利用性や保守性が向上します。しかし、これらの概念を誤って適用すると、逆に複雑さを増し、コードの可読性を低下させることがあります。

コード例(TypeScript)


class User {
    constructor(public name: string, public age: number) {}
}

class Admin extends User {
    constructor(name: string, age: number, public permissions: string[]) {
        super(name, age);
    }

    addPermission(permission: string) {
        this.permissions.push(permission);
    }
}

const admin = new Admin("Alice", 30, ["read", "write"]);
admin.addPermission("delete");

コードの行ごとの解説

  1. class User – ユーザーを表現する基本クラスを定義。
  2. constructor(public name: string, public age: number) – ユーザーの名前と年齢を初期化。
  3. class Admin extends User – ユーザーを拡張した管理者クラスを定義。
  4. constructor(name: string, age: number, public permissions: string[]) – 管理者の特権を初期化。
  5. addPermission(permission: string) – 新しい権限を追加するメソッド。
  6. const admin = new Admin("Alice", 30, ["read", "write"]) – 管理者インスタンスを作成。
  7. admin.addPermission("delete") – 権限を追加。

アンチパターン編

上記のコードは一見すると正しく見えますが、実際にはいくつかの問題を抱えています。特に、継承の過剰使用が挙げられます。AdminクラスはUserクラスから継承していますが、AdminがUserのすべての特性を持つ必要があるかは疑問です。このように、クラス間の関係が不明確になると、コードのメンテナンスが難しくなります。

改善策として、コンポジションを考慮することが有効です。AdminクラスがUserクラスを持つ形に変更することで、より柔軟な設計が可能になります。以下はその改善例です。


class User {
    constructor(public name: string, public age: number) {}
}

class Admin {
    private user: User;
    public permissions: string[];

    constructor(name: string, age: number, permissions: string[]) {
        this.user = new User(name, age);
        this.permissions = permissions;
    }

    addPermission(permission: string) {
        this.permissions.push(permission);
    }
}

const admin = new Admin("Alice", 30, ["read", "write"]);
admin.addPermission("delete");

まとめ

  • オブジェクト指向設計では、継承の使用を慎重に行うことが求められます。
  • コンポジションを利用することで、より柔軟でメンテナンスしやすいコードを実現できます。
  • 実際の業務では、アンチパターンを意識し、適切な設計を心がけることが重要です。