- 初めに
前投稿にデザインパターンについて書こうと思いましたが、デザインパターンのベースをまとめた方がいいと思い、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
日本語では「 単一責任の原則」であり、単一責任というキーワードがポイントです。単一責任の原則とは「クラスに変更が起こる理由は、一つであるべき。」です。
この原則の意味は「一つクラスは一つ役割であり、一つタスクだけ解決する」です。この原則の意味を理解するのがシンプルですが、実現が難しいです。以下のサンプルを参考にしましょう
123456789101112131415161718192021222324// RSP Violationclass 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());}}
上記のサンプルには単一責任の原則に違反していますが、なぜかというのは自分で考えてみてください。
上記のソースコードをリファクタリングし、単一責任の原則に守りましょう
123456789101112131415161718192021222324252627282930// Refactoredclass 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) いなければならない
開放/閉鎖原則の意味もシンプルですが、メリットがが有用です。
・保守性が高い
・再使用性が高い
・エラーハンドリング性が高い
もちろん開放/閉鎖原則に守るのが難しいですが、実現できたら、仕様変更対応の時に楽になるので、必ず検討しましょう。
もっと明確にするために、サンプルを分析しようと思います。
1234567891011121314151617181920212223242526272829// OCP Violationclass 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メソッドの修正が必要となります。
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849class 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)}}
しかし、三角も追加したい場合はもう一度修正が必要となるので、開放/閉鎖原則に違反しましたよね。改善しましようと思いますが改善する前に、開放/閉鎖原則をもう一度読みましょう。
その後に、リファクタリングを行います。
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647public 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.05.07オフショア開発の失敗要因
- オフショア開発2020.02.18ベトナムでのAIの提供モデル
- 技術開発2018.06.06シングルトンパターン深く議論
- WEB2017.10.19Laravelチップシリーズ 2:SOLIDの世界1