2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JavaScriptにおけるクラス設計:責務分離と継承/委譲の選定戦略

Posted at

概要

JavaScriptにおけるクラス設計は、ただの構文糖ではない。
それは**“責務を定義し、オブジェクトの振る舞いを明示的に構造化するための設計戦略”**である。

継承(extends)を使うのか、委譲(composition)でまとめるのか。
これは機能の共通化だけでなく、可読性・拡張性・責任の局所性を左右する重大な設計判断だ。

本稿では、JavaScriptにおけるクラス設計の原則、継承と委譲の使い分け、責務の分割戦略を包括的に整理する。


1. クラスの基本構造と責務定義

class User {
  constructor(name, role) {
    this.name = name;
    this.role = role;
  }

  greet() {
    return `Hello, ${this.name}`;
  }
}
  • ✅ 状態(プロパティ)と振る舞い(メソッド)をひとまとめに定義
  • ✅ クラス1つにつき「1つの責任」が原則(SRP)

2. 継承:親子関係で構造を拡張する

class Admin extends User {
  constructor(name) {
    super(name, 'admin');
  }

  hasAccess() {
    return true;
  }
}
  • is-a 関係が成り立つ場合のみ採用
  • ✅ 基本クラスの振る舞いを 拡張・オーバーライドできる

3. 委譲(Composition):機能の再利用と柔軟性の確保

class Logger {
  log(msg) {
    console.log(`[LOG]: ${msg}`);
  }
}

class Task {
  constructor(name, logger) {
    this.name = name;
    this.logger = logger;
  }

  run() {
    this.logger.log(`Running ${this.name}`);
  }
}
  • ✅ 機能の再利用を目的とする場合は has-a(委譲) を採用
  • ✅ コンポーネント単位で機能を差し替えやすく、テストもしやすい

4. 継承 vs 委譲:判断基準

観点 継承(extends) 委譲(composition)
関係性 is-a has-a
構造の固定度 高い 低い(差し替え可能)
再利用性 限定的 高い
拡張性 サブクラスごとに増殖 必要部品だけ差し替え可能
テスト容易性 状態を持ちやすく重い 単機能なので軽量

5. 抽象化とインタフェース設計の意識(TypeScriptとの連携)

interface Storable {
  save(): void;
}

class FileStore implements Storable {
  save() {
    // ファイルへ保存
  }
}

class DBStore implements Storable {
  save() {
    // DBへ保存
  }
}
  • 具象に依存せず、振る舞いの契約で設計できる
  • ✅ 複数の実装を 構文レベルで切り替え可能

設計判断フロー

① クラスが担う責務は1つに明確化されているか?

② 継承の関係は is-a を満たすか? → それ以外なら委譲を検討

③ 再利用したいのは構造か振る舞いか? → 構造なら委譲が向く

④ テスト対象の振る舞いを独立させやすいか?

⑤ 構成要素はコンポーネントとして交換可能に設計されているか?

よくあるミスと対策

❌ 機能ごとにクラスを分けず、全てを1クラスに集約

→ ✅ 単一責任原則(SRP)を意識して分割


❌ 明確な is-a 関係がないのに extends を使っている

→ ✅ 機能の再利用は委譲で行い、構造の健全性を保つ


❌ クラスに直接Loggerや依存物を埋め込み、差し替えが困難

→ ✅ 外部から注入(DI)し、柔軟性を担保


結語

クラスは「便利な構文」ではない。
それは**“振る舞いと状態を構造として統合し、責任ある抽象化を行うための設計戦略”**である。

  • 継承は拡張のために、委譲は柔軟性のために使う
  • SRP・テスト容易性・構造の健全性をすべて意識する
  • 機能単位で分離されたオブジェクト設計こそが、保守性を最大化する

JavaScriptにおけるクラス設計とは、
“責務と構造を秩序化し、進化に耐える抽象的インタフェースを構築する戦略である。”

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?