­

设计模式六大原则(二)

  • 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();      }  }