依赖倒置的核心是高层模块不该该依赖低层模块,两者都应该依赖其抽象;抽象不该该依赖细节;细节应该依赖抽象。具体一点说:安排一件事给某一我的作,咱们不该该限制是某一种人,好比小孩、青年、老人等,而是限制为人,这样作的好处就是若是有不一样的事情,能够不一样的人完成。好比跨栏,就用青年人完成。这个例子中的高层模块是“事”,依赖的模块是“人”,底层模块是“小孩、青年、老人等”,“人”是底层模块的抽象,固然,“事”也是一个抽象,“跨栏”则是底层模块的细节。
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(); } }