0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Clean Architecture】ISP: Interface Segregation Principle(インターフェース分離の原則)

Last updated at Posted at 2025-09-29

はじめに

SOLID 原則の 4 つ目は ISP(インターフェース分離の原則) です。
これは 「大きすぎるインターフェースを分割し、利用者に不要な依存を強要しない」 という考え方で、クリーンな設計を維持するうえで欠かせません。


1. 定義

インターフェース分離の原則(ISP) とは:

クライアントは、自分が使わないメソッドに依存してはならない。


2. 直感的な例

ISP 違反(インターフェースが肥大化)

interface Worker {
    fun work()
    fun eat()
    fun sleep()
}

class Robot : Worker {
    override fun work() { println("Working...") }
    override fun eat() { throw UnsupportedOperationException("Robot doesn't eat!") }
    override fun sleep() { throw UnsupportedOperationException("Robot doesn't sleep!") }
}
  • ロボットは「食べる」「寝る」を持たないのに、無理やり実装させられている
  • 利用側も「本当にこのメソッド使えるの?」と混乱する

ISP 準拠(役割ごとに分離)

interface Workable { fun work() }
interface Eatable { fun eat() }
interface Sleepable { fun sleep() }

class Human : Workable, Eatable, Sleepable {
    override fun work() = println("Working...")
    override fun eat() = println("Eating...")
    override fun sleep() = println("Sleeping...")
}

class Robot : Workable {
    override fun work() = println("Working...")
}
  • クライアントは必要なインターフェースだけ依存できる
  • 依存の最小化が実現

3. Flutter / Android での例

Flutter

// NG: 1つのインターフェースに責務を詰め込みすぎ
abstract class Storage {
  void save(String key, String value);
  String load(String key);
  void clearCache();  // 全クライアントが必要とは限らない
}

// OK: 責務ごとに分離
abstract class Savable {
  void save(String key, String value);
}

abstract class Loadable {
  String load(String key);
}

abstract class CacheClearable {
  void clearCache();
}

→ Web用ストレージ、モバイル用ストレージなどで「必要な機能だけ」実装可能。


Android (Kotlin)

//  NG
interface Printer {
    fun print()
    fun scan()
    fun fax()
}

class SimplePrinter : Printer {
    override fun print() { println("Printing...") }
    override fun scan() { throw UnsupportedOperationException() }
    override fun fax() { throw UnsupportedOperationException() }
}

// OK
interface Printable { fun print() }
interface Scannable { fun scan() }
interface Faxable { fun fax() }

class SimplePrinter : Printable {
    override fun print() = println("Printing...")
}

4. ISP 違反のデメリット

  • 実装クラスが不要なメソッドを抱える
  • テスト対象が増えてコスト増
  • 利用側が余計な知識を持たされる
  • 抽象化の意味が薄れる

5. 実務での適用ポイント

  • インターフェースは「役割」で切る」
    Repository を「Readable」「Writable」に分割する
  • クライアント単位で最小限の契約を設計する
  • レビュー時に質問する
    → 「このクラスは、このメソッドを必ず実装する必要がある?」
  • Clean Architecture と組み合わせる
    → 各層のインターフェースはユースケースや役割単位で設計

6. まとめ

  • ISP = 不要な依存を持たせない設計
  • インターフェースは「大きなひとつ」ではなく「小さな役割の集合」
  • 実装や利用がシンプルになり、テスト容易性・保守性・理解しやすさ が向上する

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?