依賴倒置的核心是高層模塊不該該依賴低層模塊,兩者都應該依賴其抽象;抽象不該該依賴細節;細節應該依賴抽象。具體一點說:安排一件事給某一我的作,咱們不該該限制是某一種人,好比小孩、青年、老人等,而是限制爲人,這樣作的好處就是若是有不一樣的事情,能夠不一樣的人完成。好比跨欄,就用青年人完成。這個例子中的高層模塊是「事」,依賴的模塊是「人」,底層模塊是「小孩、青年、老人等」,「人」是底層模塊的抽象,固然,「事」也是一個抽象,「跨欄」則是底層模塊的細節。
php
<?php namespace Factory\ReplaceModel; /** * Class WrongClassYoung * @package Factory\ReplaceModel */ class WrongClassYoung { /** * */ public function run() { echo 'biu'; } } /** * Class WrongClassHurdle * @package Factory\ReplaceModel */ 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 Factory\ReplaceModel */ interface Sportsman { /** * @return mixed */ public function start(); } /** * Class YoungSportsman * @package Factory\ReplaceModel */ class YoungSportsman implements Sportsman { /** * @return mixed|void */ public function start() { echo 'biu'; } } /** * Class ChildrenSportsman * @package Factory\ReplaceModel */ class ChildrenSportsman implements Sportsman { /** * @return mixed|void */ public function start() { echo 'biu biu'; } } /** * 運動項目 * Interface SportEvent * @package Factory\ReplaceModel */ interface SportEvent { /** * @param Sportsman $sportsman * @return mixed */ public function do(Sportsman $sportsman); } /** * 跨欄運動 * Class HurdleSportEvent * @package Factory\ReplaceModel */ class HurdleSportEvent implements SportEvent { /** * @param Sportsman $sportsman * @return mixed|void */ public function do(Sportsman $sportsman) { $sportsman->start(); } } /** * 拔河運動 * Class TugOfWar * @package Factory\ReplaceModel */ 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沒有直接關係的,它們的關係是俱樂部維持的。
spa
<?php namespace Factory\ReplaceModel; /** * Class ClubClass * @package Factory\ReplaceModel */ class ClubClass { /** * @return ClubBossClass */ public function getBoss() { return new ClubBossClass(); } } /** * Class ClubBossClass * @package Factory\ReplaceModel */ class ClubBossClass { /** * @return string */ public function getPhone() { return 'phone'; } } /** * false * Class AFalseClass * @package Factory\ReplaceModel */ class AFalseClass { /** * @param ClubBossClass $clubBossClass * @return string */ public function getClubBossPhone(ClubBossClass $clubBossClass) { return $clubBossClass->getPhone(); } } /** * true * Class ATrueClass * @package Factory\ReplaceModel */ class ATrueClass { /** * @param ClubClass $clubClass * @return string */ public function getClubBossPhone(ClubClass $clubClass) { return $clubClass->getBoss()->getPhone(); } }