设计模式六大原则(二)
- 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(); } }