SOLIDは、保守性が高く柔軟なOOPシステムを構築するための5つの設計原則です。それぞれが、硬く脆いコードの一般的な原因に対処しています。
SOLIDは、保守性が高く柔軟なOOPシステムを構築するための5つの設計原則です。それぞれが、硬く脆いコードの一般的な原因に対処しています。
| 文字 | 原則 | 一行での意味 |
|---|
| S | Single Responsibility | クラスは変わる理由を1つだけ持つべき |
| O | Open/Closed | 拡張に対して開き、修正に対して閉じている |
| L | Liskov Substitution | サブタイプは基本型が使用される場所であればどこでも使用可能であるべき |
| I | Interface Segregation | 1つの大きなインターフェースより多くの小さなインターフェース |
| D | Dependency Inversion | 具体的なクラスではなく抽象化に依存する |
# Dependency Inversion: high-level code depends on an abstraction
class Notifier: # abstraction
def send(self, msg): ...
class EmailNotifier(Notifier):
def send(self, msg): print("email:", msg)
class OrderService:
def __init__(self, notifier: Notifier): # injected abstraction
self.notifier = notifier # not "new EmailNotifier()"
def place(self):
self.notifier.send("order placed") # works with ANY Notifier
OrderServiceは特定のメールに依存していません。SMSやテストダブルと交換できます (D)。新しい通知タイプを追加してもOrderServiceへの変更は不要です (O)。
SOLIDはガイダンスであり、法則ではありません。過度に適用すると — クラスごとに1つのインターフェース、至るところに間接参照 — 解決しようとした問題より追うのが難しい「抽象化スープ」を生み出します。
SOLIDは共有の診断言語を提供します。レビュアーは好みで議論する代わりに、クラスが変更しにくい理由を名前で指摘できます ("これはSRPに違反している")。
判断力をもって適用すれば、これらの原則は波及効果を減らします。変更は局所的に留まり、新機能は書き換えではなく拡張となり、テストは実依存を偽物で置き換えられます。