這篇文章主要介紹了關於對PHP物件導向設計五大原則(SOLID)的總結,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
PHP設計原則梳理,參考《PHP核心技術與最佳實務》、《敏捷開發原則、模式與實踐》,文章PHP物件導向設計的五大原則、設計模式原則SOLID
單一職責原則(Single Responsibility Principle, SRP)
定義/特性
僅有一個引起類變化的原因
一個類只承擔一項職責(職責:變化的原因)
避免相同的職責分散到不同的類,功能重複
問題
遵守SPR原則優勢
減少類之間的耦合:當需求變化時,只修改一個類,從而隔離了變化帶來類對其他職責的影響
提高類的複用性:按需引用,一個類負責一個職責,需求的變動只需要修改對應的類或增加某一職責
降低類的複雜度:職責單一,功能分散開降低一個類多個職責類的複雜度
程式碼範例
class ParseText{ private $content; public function decodeText(String $content) { // TODO: decode content } public function saveText() { // TODO:: save $this->content; }}/*問題思考:解析的文本類型會有多種-html、xml、json儲存的文本也會有多種途徑-redis、mysql、file用戶端只需要解析文本時必須會引入saveText不需要的方法兩個職責之間沒有強烈的依賴關係存在任意職責需求變化都需要更改這個類*//*符合SRP的設計職責拆分*/class Decoder{ private $content; public function decodeText(String $content) { // TODO: decode content } public function getText() { return $this->content; }}class Store{ public function save($content) { // TODE: save }}
總結
軟體設計所做的許多內容就是發現職責併合理的分離職責間的關係。如果應用程式的變化總是同時影響多個職責,就沒必要分離職責。
介面隔離原則(Interface Segregation Principle ISP)
問題
設計應用程式時,類的介面不是內聚的。不同的用戶端只包含集中的部分功能,但系統會強制用戶端實現模組中所有方法,並且還要編寫一些啞方法。這樣的介面成為胖介面或者是介面汙染,這樣的介面會給系統引入一些不當的行為,資源浪費,影響其他用戶端程式增強了耦合性等
ISP定義/特性
不應該強迫用戶端依賴與他們不需要的方法/功能
一個類對一個類的依賴應該建立在最小的介面上
介面的實作類別應該只呈現為單一職責原則
遵循ISP原則優勢
解決方式
程式碼範例
/** 公告介面*/interface Employee{ public function startWork(); public function endWork();}/** 定義特定用戶端介面*/interface Coder{ public function writeCode();}interface Ui{ public function designPage();}class CoderClient implements Employee, Coder{ public function startWork() { //TODO:: start work time } public function endWork() { //TODO:: end work time } public function writeCode() { //TODO:: start write code return 'hellow world'; }}$c = new CoderClient();echo $c->writeCode();
總結
胖類會導致他們的用戶端程式之間產生不正常的並且有害的耦合關係。通過把胖客戶度分解成多個特定於用戶端的介面,用戶端緊緊依賴於他們實際調用的方法,從而解除了用戶端與他們沒有調用的方法之間的依賴關係。介面隔離應做的小而少。
SRP與ISP比較
開放-封閉原則(Open-Close Principle OCP)
問題
隨著軟體系統規模的不斷擴大,系統的維護和修改的複雜性不斷提高。系統一處的更改往往會影響到其他模組。正確的運用OCP原則可以解決此類問題。
定義/特性
遵循OCP優勢
程式碼範例
/** 定義有固定行為的抽象介面*/interface Process{ public function action(String $content);}/** 繼承抽象介面,擴充不同的行為*/class WriteToCache implements Process{ public function action(String $content) { return 'write content to cache: '.$content; }}class ParseText{ private $content; public function decodeText($content) { $this->content = $content; } public function addAction(Process $process) { if ($process instanceof Process) { return $process->action($this->content); } }}$p = new ParseText();$p->decodeText('content');echo $p->addAction(new WriteToCache());
總結
OCP核心思想就是抽象介面編程,抽象相對穩定。讓類依賴與固定的抽象,通過物件導向的繼承和多態讓類繼承抽象,複寫其方法或固有行為,是想新的擴充方法/功能,實現擴充。
裡氏替換原則(Liskov Substitution Principle LSP)
問題
物件導向中大量的繼承關係十分普遍和簡單,這種繼承規則是什麼,最佳的繼承層次的規則又是什麼,怎樣優雅的設計繼承關係,子類能正確的對基類中的某些方法進行重新,這是LSP原則所要處理的問題。
定義/特性
違反LSP原則
假設一個函數a,他的參數引用一個基類b,c是b的衍生類別,如果將c的對象作為b類型傳遞給a,會導致a出現錯誤的行為,那沒c就違法了LSP原則。
/** 基類*/class Computer{ public function action($a, $b) { return $a+$b; }}/** 子類複習了父類方法,改變了action 的行為* 違反了LSP原則*/class Client extends Computer{ public function action($a, $b) { return $a-$b; } }function run(Computer $computer, $a, $b) { return $computer->action($a, $b);}echo run((new Client()), 3, 5);
總結
LSP是OCP得以應用的最主要的原則之一,正是因為子類性的可替換行是的基類類型在無需修改的情況下擴充功能。
依賴倒置原則(Depend Inversion Principle DIP)
問題
軟體開發設計中,總是傾向於建立一些高層模組依賴底層模組,底層模組更改時直接影響到高層模組,從而迫使他們改變。DIP原則描述了高層次模組怎樣調用低層次模組。
定義/特性
程式碼範例
interface Arithmetic{ //public function sub($a, $b);}class Client{ public function computer(Arithmetic $arithmetic, $a, $b) { return $arithmetic->add($a, $b); }}class Addition implements Arithmetic{ public function add($a, $b) { return $a + $b; }}$c = new Client();echo $c->computer(new Addition(), 2, 3);/*client 高層類 依賴於Arithmetic,Addition底層實現細節類實現Arithmetic介面,達到二者依賴於抽象介面的DIP設計原則*/
總結
DIP原則就是每個高層次模組定義一個它所需服務的介面聲明,低層次模組實現這個介面。每個高層次類通過該抽象介面使用服務。
思考
物件導向軟體開發中合理的遵循設計原則可以更好的設計代碼,減少不必要的錯誤,提高程式的可維護性,可擴充性和穩定性。
單一職責(SRP)如何正確的劃分職責,類的職責單一提高代碼複用性,降低耦合性
介面隔離(OCP)合理劃分介面功能,保證介面的專一性,純潔性,減少依賴關係
裡氏替換(LSP)合理利用類的繼承體系,保證真確的繼承關係不被破壞
依賴倒置(DIP)抽象介面編程由於抽象具體實現
開放封閉(OCP)物件導向編程終極目標所達到的結果,類/模組/系統的功能行為可擴充,內部更改性是封閉的
以上就是本文的全部內容,希望對大家的學習有所協助,更多相關內容請關注topic.alibabacloud.com!