インターフェース分離の原則(Interface Segregation Principle: ISP)
インターフェース分離の原則(Interface Segregation Principle: ISP)は、SOLID原則の一つであり、**「クライアントは、利用しないメソッドへの依存を強制されるべきではない」**という設計指針です。これは、特に大規模なアプリケーションや柔軟なモジュール設計において重要な原則です。本記事では、上級プログラマー向けに、PythonとTypeScriptでISPが守られている例と守られていない例を比較しながら解説します。
ISPの本質
大きなインターフェースを複数の小さな特化したインターフェースに分割することで、クラスは自分が使用しない機能を実装する義務から解放されます。結果として、柔軟で変更に強く、保守性の高い設計が可能になります。
Pythonによる例(動物の動作)
❌ ISPが守られていない例
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def fly(self):
pass
@abstractmethod
def swim(self):
pass
@abstractmethod
def walk(self):
pass
class Dog(Animal):
def fly(self):
raise NotImplementedError("Dog can't fly")
def swim(self):
print("Dog swims")
def walk(self):
print("Dog walks")
Dog
クラスに不要な fly()
メソッドの実装が強制されており、明らかに不自然です。
✅ ISPが守られている例
from abc import ABC, abstractmethod
class Walkable(ABC):
@abstractmethod
def walk(self):
pass
class Swimmable(ABC):
@abstractmethod
def swim(self):
pass
class Flyable(ABC):
@abstractmethod
def fly(self):
pass
class Dog(Walkable, Swimmable):
def walk(self):
print("Dog walks")
def swim(self):
print("Dog swims")
class Bird(Walkable, Flyable):
def walk(self):
print("Bird walks")
def fly(self):
print("Bird flies")
Dog
や Bird
は自身が必要とするインターフェースのみを実装し、ISPが守られています。
TypeScriptによる例(ロボットの機能)
❌ ISPが守られていない例
interface Robot {
clean(): void;
cook(): void;
dance(): void;
}
class CleaningRobot implements Robot {
clean(): void {
console.log("Cleaning room");
}
cook(): void {
throw new Error("Cannot cook");
}
dance(): void {
throw new Error("Cannot dance");
}
}
CleaningRobot
は掃除しか行えないにもかかわらず、他の機能の実装を強制されています。
✅ ISPが守られている例
interface Cleaner {
clean(): void;
}
interface Cook {
cook(): void;
}
interface Dancer {
dance(): void;
}
class CleaningRobot implements Cleaner {
clean(): void {
console.log("Cleaning room");
}
}
class MultiFunctionRobot implements Cleaner, Cook, Dancer {
clean(): void {
console.log("Cleaning room");
}
cook(): void {
console.log("Cooking food");
}
dance(): void {
console.log("Dancing to music");
}
}
CleaningRobot
も MultiFunctionRobot
も、それぞれ必要な機能だけを実装しており、ISPを正しく守っています。
まとめ
インターフェース分離の原則は、過剰な依存からコードを守り、関心ごとの分離を徹底することで、堅牢で拡張しやすいソフトウェアを実現します。上級開発者としては、抽象を扱う際に汎用性と最小限性のバランスを見極め、インターフェース設計を常に見直す姿勢が求められます。