SOLID原則を学んでいます
「Software Design (ソフトウェアデザイン) 2023年6月号 [雑誌]」という雑誌に出会ったので、SOLID原則を学習中です。これを機に3流プログラマーに慣れたらいいなぁと。
前回の学習内容はこちら
まずはInterfaceから
PHPにおけるInterface(インターフェース)は、クラスが実装するべきメソッドのシグネチャ(メソッド名、引数、戻り値の型)を定義するための機能です。
Interfaceは抽象的なクラスであり、実際の実装を持ちません。
(じゃあいらんやん...って思っちゃいますよね)
なぜ必要なのかというと、
クラスはInterfaceを実装することで、そのInterfaceで定義されたメソッドを必ず実装しなければならないからです。
例えば、ユーザーにメッセージを送信する場面を考えて下さい。
どの様なメッセンジャーを使うにしても必ず「メッセージを生成する機能」と「メッセージを送信する機能」の2つが必要になるはずです。
ここではメールで送信する場合(メールクラス)とLineで送信する場合(Lineクラス)を想定してみます。
interfaceを以下のように定義することで、実装したクラスはinterfaceの内容を必ず実装しなければいけません。
interface Message {
public function createMesseage();
public function sendMessage();
}
上記の様に定義することで、メールクラスとLineクラスは必ず同じメソッドがある事が担保されます。(クラスは同じ振る舞いを持つことが保証されます)
仮にSlackでメッセージを送信したい場合、Slackクラスに同じメソッドを実装するだけで済むため拡張性が高くなりますよね。あら、わかりやすい。笑
(既存のクラス(メールクラス、Lineクラス)に影響なく実装できる)
class Mail implements Message {
public function createMessage() {
//処理
}
public function sendMessage() {
//処理
}
}
class Line implements Message {
public function createMessage() {
//処理
}
public function sendMessage() {
//処理
}
}
interface Message {
public function createMessage() {}
public function sendMessage() {}
}
いよいよ依存性反転の原則
一旦、呼び出し元の観点を持ってみましょう。
interfaceを実装することで、呼び出し元のコードはinterfaceに対して依存し、具体的な実装クラスに対して依存しないためコードの結合が低くなります(疎結合。。。)
先程のコードで考えると呼び出し元はメールクラスを呼び出しているつもりでもinterfaceを経由しているのが実態です。
Interfaceを使用することで、クラス間の依存関係を抽象化し、実装にではなくインターフェースに依存するようにすることができます。
- 呼び出し元の見ているところがinterfaceになる
- interfaceは定義する場所
- interfaceを継承したクラスは必ず同じメソッドある
- 結果、呼び出し元と実装クラスはinterfaceに依存している
これにより、依存性反転原則が達成されます。
ちゃんちゃん。