はじめに
こんにちは!ちびまろです。
SOLID原則(後述)について、全5回に分けて紹介していければと思っています。
前提条件
この記事を読むにあたり、クラス・メソッドの意味と基本的な使い方を知っていればスムーズに理解することができると思います。
SOLID原則とは
さてみなさん、SOLID原則について聞いたことはありますか?
恥ずかしながら私は最近耳にしました😅
きっかけは@baby-degu(baby degu)さんの投稿。
私個人設計を勉強してこなかったのもそうですが、何よりも耳にしたことがないことに驚いたので早速調べてみました。
SOLID原則とは、オブジェクト指向プログラミングとソフトウェア設計のための5つの設計原則のことです。
簡単に言うと、「オブジェクト指向に乗っ取ったシステムはこうやって作るべきだよね。こう書くべきだよね。」を決めたルールブックのようなもの。だと私なりに勝手に落とし込みました。
厳密には違うかもしれませんが、色々なサンプルコードを読みつつも上記のイメージがスッキリ入ってきたのであくまでイメージだと理解した上で読んでいただけると幸いです!
五つの原則は以下の通りです。
- 単一責任の原則(single-responsibility principle)
- 開放閉鎖の原則(open / closed principle)
- リスコフの置換原則(Liskov substitution principle)
- インターフェース分離の原則(interface segregation principle)
- 依存性逆転の原則(dependency inversion principle)
その中でも今回はSOLID原則の中の一つである「S」にあたる単一責任の原則について説明します。
単一責任の原則(Single Responsibility Principle)
正直「単一責任の原則とか言われても~」って感じですよね。
私も最初はそうでした(笑)
でも安心してください!中身は非常にシンプルです!
そこで少しでも理解が深まるよう、単一責任の原則の説明をしたのちに「原則に準拠したコード」と「原則に反したコード」を書きます。
単一責任の原則とは、クラスは一つの責任だけを持つべきであるというものです。
簡単に言うと、一つのクラスの中には、そのクラスに関するロジックのみ実装しましょう。といった感じですかね!
と言ってもまぁ中々イメージ出来ないですよね(笑)
実際のコードを用意したため、それぞれ比較しつつ、実際に書きながら一緒に学んでいきましょう。
単一責任の原則に反したコード
同じUserクラスの中で、「ユーザ情報関連」「ログイン関連」「出力関連」と役割の異なるメソッドがUser
という1つのクラスに集約されています。
これではUserクラス
が何の役割を担っているのか。つまり、どのような責務を担当しているのかが分かりません。
class User{
private getUserName;
private getEmail;
private getPassword;
// ユーザー名を取得
public function getUserName(){
return $this->userName;
}
// Eメールを取得
public function getEmail(){
return $this->getEmail;
}
// パスワードを取得
public function getPassword(){
return $this->getPassword;
}
// ログイン
public function login(){
// 省略
}
// ログアウト
public function logout(){
// 省略
}
// Json形式の出力メソッド
public function exportJson(){
// 省略
}
}
そこで出てくるものが次のものです。
単一責任の原則に準拠したコード
ちゃんと役割ごとにクラスを分けよう!という考えです。
各クラスごとに明確な役割を振り分けてあげることで、今後修正する際の影響範囲を小さくすることができます。
原則に準拠することで、全部で3つのクラスに分けられました!
// ユーザ情報に関するクラスで1クラス目
class User{
private getUserName;
private getEmail;
private getPassword;
// ユーザー名を取得
public function getUserName(){
return $this->userName;
}
// Eメールを取得
public function getEmail(){
return $this->getEmail;
}
// パスワードを取得
public function getPassword(){
return $this->getPassword;
}
}
// 認証(ログイン・ログアウト)に関するクラスで2クラス目
class Auth{
public function login(){
// 省略
}
public function logout(){
// 省略
}
}
// 出力に関するクラスで3クラス目
class Output{
// Json形式の出力メソッド
public function exportJson(){
// 省略
}
}
単一責任の原則に従うことによる主なメリット
色々メリットがありますが、厳選して3つご紹介します。
- 再利用性の向上
- テストの容易さ
- バグの減少
再利用性の向上
一つの特定の機能に焦点を当てることで、他のコンポーネントやアプリケーションでも再利用しやすくなります。
テストの容易さ
単一責任を持つクラスは、テストコードを書く形式のテストが行いやすくなります。
特定の機能に特化していることで、他の機能やクラスへの影響を感じることが少ないです。
また、少ないテストケースで網羅的にテストをすることができます。
バグの減少
責任が明確に分離されていることで、バグが発生しにくくなります。
一つのクラスに複数の責任がある場合、1行の修正で意図しないデグレを発生させてしまう可能性が高まります。
さいごに
最後まで読んでいただきありがとうございました!
SOLID原則のうちの一つである単一責任の原則は理解できましたか?
もしまだ難しいと感じた方がいる場合は、コメントいただけると嬉しいです!
時間がある時に何かより良い伝え方がないか考えてみます!
コメント