SOLID:php
- S: 單一職責原則 (SRP)
- O: 開閉原則 (OCP)
- L: 里氏替換原則 (LSP)
- I: 接口隔離原則 (ISP)
- D: 依賴反轉原則 (DIP)
- 迪米特法則
解耦和加強內聚性(高內聚,低耦合),一個類和方法的只負責一個職責html
class Activity { public function getActivity() { if ($this->startDate < time() && $this->endDate > time()) { return '活動:' . $this->name . '已經在' . date('Y-m-d H:i:s', $this->startDate) . '開始'; } else { return '活動:' . $this->name . '沒有開始'; } } }
弊端:若是再增長條件,和輸出修改,會加劇邏輯。
改變爲 ->segmentfault
class Activity { public function getActivity() { return $this->isStart ? $this->getStartWord() : $this->getEndWord(); } public function isStart() { return $this->startDate < time() && $this->endDate > time(); } public function getStartWord() { return '活動:' . $this->name . '已經在' . date('Y-m-d H:i:s', $this->startDate) . '開始'; } public function getNotStartWord() { return '活動:' . $this->name . '沒有開始'; } }
class Activity { public function __construct(Activity $activity) { $this->activity = $activity; } public function draw() { if ($this->isStart()) { return $this->draw(); } throw Exception('沒有開始'); } }
弊端:類的職責不清。抽獎和活動不該該屬於同一個類
更改成->設計模式
class Activity { public function __construct(Activity $activity) { $this->activity = $activity; $this->config = '38_festival'; } public function draw() { if ($this->isStart()) { return $this->initDrawManage->draw(); } throw Exception('沒有開始'); } public function initDrawManage() { !isset($this->drawManage) && $this->drawManage = new DrawManage($this->config) return $this->drawManage } } class DrawManage { public function __construct($config) { $this->config = $config } public function draw() { ... } }
對擴展開放,對修改關閉。
與其修改別人的代碼(或者老代碼)不如先繼承,而後更改。ide
interface UserInterface { public function getUserIdentify(); } class User implements UserInterface { private $identify = '先生/女士'; public function getUserIdentify { return $this->name . $this->identify; } }
改成->學習
interface UserInterface { public function getUserIdentify(); } class User implements UserInterface { private $identify = '先生/女士'; public function getUserIdentify { return $this->name . $this->identify; } } class Student extend User { private $identify = '學生'; }
增長新的角色和工種時優化
interface UserInterface { public function getUserIdentify(); } class User implements UserInterface { private $identify = 'young'; public function getUserIdentify() { return $this->identify; } } class Student extend User { private $identify = 'student'; } class Work { private $identify public function __construct(UserInterface $identify) { $this->identify = $identify; } public function getWorking() { return $this->identify->getIdentify() == 'student' ? $this->study() : $this->working(); } public function study() { return '學習'; } public function wordking() { return '工做'; } }
弊端:修改代碼~~
更改Work類的代碼->this
interface UserInterface { public function getUserIdentify(); public function doing(); } class User implements UserInterface { private $identify = 'young'; public function getUserIdentify() { return $this->identify; } public function doing() { return 'working'; } } class Student extend User { private $identify = 'student'; public function doing() { return 'study'; } } class Work { private $identify public function __construct(UserInterface $identify) { $this->identify = $identify; } public function getWorking() { return $this->identify->doing(); } }
父類出現的地方子類就能夠出現,且替換成子類也不會出現任何錯誤或者異常。spa
針對接口的原則,規範以下:.net
示例:
interface User { public function working(); public function studing(); } class Student implements User { public function working() { // 學生不工做(假設) return null; } ... } class Worker implements User { public fucntion studing { // 不學習(假設) return null; } }
能夠修改->
interface StudentInterface { public function studing(); } interface WorkerInterface { public function working(); } class Student implements StudentInterface { ... } class Worker implements WorkerInterface { ... }
高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象。
這個原則恰好本文的第二小節開閉原則示例1貌似就違反了,可是要看具體業務的,若是是A是父類,B是子類,具備必定的聯繫,沒法分割就不遵循。若是A類和B類是平級關係,繼承只是共用一些方法,那就有必要讓二者都依賴抽象,便於該改動。
迪米特法則也叫作最少知識原則(Least Knowledge Principle,LKP),即一個對象應該對其餘對象有最少的瞭解。不關心其餘對象內部如何處理。
根據實際狀況使用不一樣的原則,可使得程序下降耦合和冗餘代碼,優化程序。根據這些規則,會有一系列的設計模式,在實際使用時不必強行套用設計模式,須要根據業務實際劃分合理便可。長城不是一天就能修好的~~~