インターフェース分離の法則

インターフェース分離の法則(Interface Segregation Principle、ISP)は、SOLID原則の一つで、クラスに必要なメソッドのみを提供するインターフェースを作成し、不要なメソッドを含まないようにすることを提唱しています。これにより、クラスの役割が明確になり、変更に強い設計を実現できます。


シナリオ:インターフェース分離の法則を適用する

あるプロジェクトで、複数の異なるタイプのオブジェクトがあるとします。それぞれのオブジェクトは、異なる機能を必要としています。このシナリオでは、各オブジェクトに必要なメソッドだけを提供するインターフェースを作成します。

悪い例:大きなインターフェースを使用

まずは、すべての機能を一つの大きなインターフェースで提供する悪い例を見てみましょう。

from abc import ABC, abstractmethod

class WorkerInterface(ABC):
    @abstractmethod
    def work(self):
        pass

    @abstractmethod
    def eat(self):
        pass

class Worker(WorkerInterface):
    def work(self):
        print("Working")

    def eat(self):
        print("Eating")

class Robot(WorkerInterface):
    def work(self):
        print("Working")

    def eat(self):
        # ロボットは食事をしないが、インターフェースの実装を強制される
        raise NotImplementedError("Robots do not eat")

worker = Worker()
worker.work()
worker.eat()

robot = Robot()
robot.work()
try:
    robot.eat()
except NotImplementedError as e:
    print(e)

# 悪い点:
# 1. ロボットのようなオブジェクトは食事のメソッドを必要としないが、インターフェースに含まれているため実装を強制される。
# 2. 不要なメソッドを実装することで、コードが冗長になり、メンテナンスが難しくなる。

この例では、WorkerInterfaceがworkとeatの両方のメソッドを提供しています。しかし、ロボットはeatメソッドを必要としないため、実装を強制されるとエラーが発生します。


良い例:インターフェース分離の法則を適用

次に、インターフェース分離の法則を適用し、各クラスに必要なメソッドのみを提供する良い例を見てみましょう。

from abc import ABC, abstractmethod

class Workable(ABC):
    @abstractmethod
    def work(self):
        pass

class Eatable(ABC):
    @abstractmethod
    def eat(self):
        pass

class Worker(Workable, Eatable):
    def work(self):
        print("Working")

    def eat(self):
        print("Eating")

class Robot(Workable):
    def work(self):
        print("Working")

worker = Worker()
worker.work()
worker.eat()

robot = Robot()
robot.work()
# ロボットには eat メソッドがないため、必要な機能だけを提供する

良い点

• WorkableインターフェースとEatableインターフェースに分離することで、クラスが必要なメソッドのみを実装できるようになりました。
• Workerクラスはworkとeatの両方のメソッドを実装し、Robotクラスはworkメソッドのみを実装しています。
• 不要なメソッドを実装する必要がなくなるため、コードがシンプルでメンテナンスしやすくなります。

結論

インターフェース分離の法則に従うことで、クラスに必要なメソッドのみを提供するインターフェースを作成し、不要なメソッドを含まないようにすることができます。これにより、コードの冗長性が減り、メンテナンス性が向上します。異なるクラスに対して必要な機能のみを提供することで、ソフトウェアの設計がより柔軟で理解しやすくなります。

この記事が気に入ったらサポートをしてみませんか?