設計模式六大原則(二)
- 2019 年 10 月 7 日
- 筆記
依賴倒置原則
依賴倒置的核心是高層模組不應該依賴低層模組,二者都應該依賴其抽象;抽象不應該依賴細節;細節應該依賴抽象。具體一點說:安排一件事給某一個人做,我們不應該限制是某一種人,比如小孩、青年、老人等,而是限制為人,這樣做的好處就是如果有不同的事情,可以不同的人完成。比如跨欄,就用青年人完成。這個例子中的高層模組是「事」,依賴的模組是「人」,底層模組是「小孩、青年、老人等」,「人」是底層模組的抽象,當然,「事」也是一個抽象,「跨欄」則是底層模組的細節。
<?php namespace FactoryReplaceModel; /** * Class WrongClassYoung * @package FactoryReplaceModel */ class WrongClassYoung { /** * */ public function run() { echo 'biu'; } } /** * Class WrongClassHurdle * @package FactoryReplaceModel */ class WrongClassHurdle { /** * @param WrongClassYoung $wrongClassYoung */ public function do(WrongClassYoung $wrongClassYoung) { $wrongClassYoung->run(); } } $wrongClassYoung = new WrongClassYoung(); $wrongClassHurdle = new WrongClassHurdle(); // 此種方式限制很多,只能做跨欄運動,也只能青年人參加。 // 如果需要添加一項運動,則需要重新添加新的類,由於沒有對類的限制,可能實現方法不同,比如,賽跑start(),拔河start(), // 這就需要我們知道每一項運動的開始方法,工作量大,且容易混亂 $wrongClassHurdle->do($wrongClassYoung); // 優化後的類 // 運動員 /** * Interface Sportsman * @package FactoryReplaceModel */ interface Sportsman { /** * @return mixed */ public function start(); } /** * Class YoungSportsman * @package FactoryReplaceModel */ class YoungSportsman implements Sportsman { /** * @return mixed|void */ public function start() { echo 'biu'; } } /** * Class ChildrenSportsman * @package FactoryReplaceModel */ class ChildrenSportsman implements Sportsman { /** * @return mixed|void */ public function start() { echo 'biu biu'; } } /** * 運動項目 * Interface SportEvent * @package FactoryReplaceModel */ interface SportEvent { /** * @param Sportsman $sportsman * @return mixed */ public function do(Sportsman $sportsman); } /** * 跨欄運動 * Class HurdleSportEvent * @package FactoryReplaceModel */ class HurdleSportEvent implements SportEvent { /** * @param Sportsman $sportsman * @return mixed|void */ public function do(Sportsman $sportsman) { $sportsman->start(); } } /** * 拔河運動 * Class TugOfWar * @package FactoryReplaceModel */ class TugOfWar implements SportEvent { /** * @param Sportsman $sportsman * @return mixed|void */ public function do(Sportsman $sportsman) { $sportsman->start(); } } $tugOfWar = new TugOfWar(); // 青年拔河比賽 $youngSportMan = new YoungSportsman(); $tugOfWar->do($youngSportMan); // 兒童拔河比賽 $childrenSportsman = new ChildrenSportsman(); $tugOfWar->do($childrenSportsman); // 優化後的類中,運動員可以靈活替換,不會改動程式碼內部構造,也不會對已有的內容造成影響。 //其中運動項目也可以再進行優化,優化至項目可以靈活更換 介面隔離原則
這裡的介面並不是「interface」,介面隔離原則的核心是只用自己需要的介面。比如:我們吃飯的時候,有套餐,套餐一般會便宜一些,且已經搭配合理。但是如果套餐中有我們不喜歡的,那麼套餐對我們而言就是不好的,這個時候我們就需要單點(隔離),我們可以根據自己需要的去自由搭配。介面隔離原則就如同吃飯單點一樣,我們只獲取自己需要的,不需要的一概不要
迪米特法則
之和直接朋友交流是迪米特法則的核心思想,比如B是A的朋友,C是B的朋友,則A不能直接和C交際。程式中最容易出現這種情況,為了方便,直接調用一個毫不相關的類。比如:A(PeopleClass),屬於一個俱樂部(ClubClass),俱樂部老闆(ClubBossClass),當我們需要獲取A所屬俱樂部老闆的手機號時,很可能會直接調用老闆的類,而跳過俱樂部。但俱樂部老闆和A沒有直接關係的,它們的關係是俱樂部維持的。
<?php namespace FactoryReplaceModel; /** * Class ClubClass * @package FactoryReplaceModel */ class ClubClass { /** * @return ClubBossClass */ public function getBoss() { return new ClubBossClass(); } } /** * Class ClubBossClass * @package FactoryReplaceModel */ class ClubBossClass { /** * @return string */ public function getPhone() { return 'phone'; } } /** * false * Class AFalseClass * @package FactoryReplaceModel */ class AFalseClass { /** * @param ClubBossClass $clubBossClass * @return string */ public function getClubBossPhone(ClubBossClass $clubBossClass) { return $clubBossClass->getPhone(); } } /** * true * Class ATrueClass * @package FactoryReplaceModel */ class ATrueClass { /** * @param ClubClass $clubClass * @return string */ public function getClubBossPhone(ClubClass $clubClass) { return $clubClass->getBoss()->getPhone(); } }


