- 初めに
前投稿にデザインパターンについて書こうと思いましたが、デザインパターンのベースをまとめた方がいいと思い、Laravelと関係があまりないですが、個人的にとても大切だと思うため、当投稿を作成し、チップシリーズ に追加したいと思います。有用であれば、「いいね」つけていただければ幸いです。
- なぜSOLIDの世界
SOLIDとは
・Single responsibility principle
・Open/closed principle
・Liskov substitution principle
・Interface segregation principle
・Dependency inversion principle
です。なぜSOLIDが大切だかみんなさんご存知だと思いますが、説明します。SOLIDはOOPの原則であり、明確にしないといけないことです。SOLIDを提供するのはメリットは:
・保守性が高い
・拡張性が高い
・エラーハンドリング性が高い
なのでOOP使ったら、当然SOLIDを重視するのが必要でしょう。SOLIDの世界に入りましょう。
- Single responsibility principle
日本語では「 単一責任の原則」であり、単一責任というキーワードがポイントです。単一責任の原則とは「クラスに変更が起こる理由は、一つであるべき。」です。
この原則の意味は「一つクラスは一つ役割であり、一つタスクだけ解決する」です。この原則の意味を理解するのがシンプルですが、実現が難しいです。以下のサンプルを参考にしましょう// RSP Violation class Post { public function getTitle() { return "Welcome to SOLID's world"; } public function getAuthor() { return "Laziii"; } public function getPostDetails() { return [ 'title' => $this->getTitle(), 'author' => $this->getAuthor(), 'content' => 'SOLID is simple principle but hard to apply' ]; } public function genPostJson() { return json_encode($this->getPostDetails()); } }
上記のサンプルには単一責任の原則に違反していますが、なぜかというのは自分で考えてみてください。
上記のソースコードをリファクタリングし、単一責任の原則に守りましょう// Refactored class Post { public function getTitle() { return "Welcome to SOLID's world"; } public function getAuthor() { return "Laziii"; } public function getPostDetails() { return [ 'title' => $this->getTitle(), 'author' => $this->getAuthor(), 'content' => 'SOLID is simple principle but hard to apply' ]; } } interface PostFormattable { public function format(Post $post); } class JsonPostFormatter implements PostFormattable { public function format(Post $post) { return json_encode($post->getPostDetails()); } }
- Open – closed principle
日本語では「開放/閉鎖原則」であり、もちろんキーワードは「開放/閉鎖」です。開放/閉鎖原則というのは
・拡張に対して開いて (open) いなければならず
・修正に対して閉じて (closed) いなければならない
開放/閉鎖原則の意味もシンプルですが、メリットがが有用です。
・保守性が高い
・再使用性が高い
・エラーハンドリング性が高い
もちろん開放/閉鎖原則に守るのが難しいですが、実現できたら、仕様変更対応の時に楽になるので、必ず検討しましょう。
もっと明確にするために、サンプルを分析しようと思います。// OCP Violation class Square { protected $width; protected $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function getWidth() { return $this->width; } public function getHeight() { return $this->height; } } class AreaCalculator { public function calculate($squares) { foreach ($squares as $square) { $area[] = square->getWidth() * square->getHeight(); } return array_sum($area) } }
この実装方は問題なさそうですよね。でもちょっと仕様を変更しようと思ったら、$squaresに四角だけではなく、丸等もある場合は、calculateメソッドの修正が必要となります。
class Square { protected $width; protected $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function getWidth() { return $this->width; } public function getHeight() { return $this->height; } } class Circle { protected $radius; function __construct($radius) { $this->radius = $radius; } public function getRadius() { return $this->radius; } } class AreaCalculator { public function calculate($shapes) { foreach ($shapes as $shape) { // $area[] = square->getWidth() * square->getHeight(); if (is_a($shape, 'Square')) { $area[] = square->getWidth() * square->getHeight(); } else { area[] = $shape->getRadius() * $shape->getRadius() * pi(); } } return array_sum($area) } }
しかし、三角も追加したい場合はもう一度修正が必要となるので、開放/閉鎖原則に違反しましたよね。改善しましようと思いますが改善する前に、開放/閉鎖原則をもう一度読みましょう。
その後に、リファクタリングを行います。public interface Shape { public function area(); } class Square implements Shape { protected $width; protected $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function area() { return $width * $height; } } /** * */ class Circle implements Shape { protected $radius; function __construct($radius) { $this->radius = $radius; } public function area() { return $radius * $radius * pi(); } } class AreaCalculator { public function calculate($shapes) { foreach ($shapes as $shape) { $area[] = $shape->area(); } return array_sum($area) } }
- まとめ
上記に「 単一責任の原則」と「開放/閉鎖原則」について説明しましたが、私の方も不明点がたくさんありますから、みなさまに補足いただければ幸いです。次の投稿でも引き続きSOLIDの世界を紹介しようと思います。やる気が上がるので、有用であれば、「いいね」つけていただければ幸いです。
- 参考
単一責任の原則
開放/閉鎖原則
SOLID
投稿者プロフィール
最新の投稿
- 受託開発2020年5月7日オフショア開発の失敗要因
- 機械学習・ディープラーニング2020年2月18日ベトナムでのAIの提供モデル
- 技術開発2018年6月6日シングルトンパターン深く議論
- Server2017年10月19日Laravelチップシリーズ 2:SOLIDの世界1