本文へスキップ
BecomeCoder

C#オブジェクト指向コース · 第3章 SOLID原則 · レッスン24

インターフェース分離の原則(I)

ブラウザで完結

導入

Interface Segregation Principle——「使わないメソッドを実装させない」。巨大なインターフェースは、それを実装するクラスに不要な負担を強います。小さく分けるのが正解です。

図解

flowchart TB
    subgraph Before["肥大化"]
        BIG["IMachine<br/>Print / Scan / Fax<br/>(単機能プリンタも全部実装させられる)"]
    end
    subgraph After["分離"]
        P["IPrinter.Print()"]
        S["IScanner.Scan()"]
    end
    Before -->|役割ごとに分割| After

サンプル

// ✅ 必要な契約だけを実装できるよう、小さく分ける
IPrinter printer = new SimplePrinter();
printer.Print("資料");   // 印刷: 資料

interface IPrinter { void Print(string doc); }
interface IScanner { void Scan(string doc); }

// 印刷しかできない機器は IPrinter だけ実装すればよい(Scan を強制されない)
class SimplePrinter : IPrinter
{
    public void Print(string doc) => Console.WriteLine($"印刷: {doc}");
}

// 複合機は両方を実装する
class AllInOne : IPrinter, IScanner
{
    public void Print(string doc) => Console.WriteLine($"印刷: {doc}");
    public void Scan(string doc) => Console.WriteLine($"スキャン: {doc}");
}
  • 大きな1つより、小さな複数のインターフェースに分ける
  • 実装クラスは必要な契約だけを選んで実装できる
  • 「このクラスにこのメソッドは本当に要るか?」が分割の判断基準

演習

IReadable file = new TextFile();
Console.WriteLine(file.Read());   // ファイルの中身

// TODO: IReadable(Read() → string)だけを実装する TextFile を定義してください
//       (書き込み機能は今回のクラスには持たせない = 使わない契約を強制しない)
interface IReadable { string Read(); }
interface IWritable { void Write(string data); }
___
  • 期待される出力: ファイルの中身
ヒント1を見る

class TextFile : IReadable { public string Read() => "ファイルの中身"; }

ヒント2を見る

IWritableは実装せず、必要なIReadableだけを実装します

まとめ

  • インターフェース分離の原則:使わないメソッドを強制しない
  • 大きな契約は小さく分ける
  • 実装クラスは必要な契約だけを選べる

次回: SOLIDの総仕上げ「依存性逆転の原則」です。

実際に動かしてみよう

本文のサンプルや演習のコードは、コードブロック右上の「コピー」ボタンでコピーして、下のエディタに貼り付ければそのまま実行できます。

C# — ブラウザ内で実行

ブラウザ内でC#を動かす環境を読み込みます(初回のみ数秒)。
スクロールして表示された時点でも自動で読み込まれます。