• 售前

  • 售后

热门帖子
入门百科

PHP面向对象五大原则之单一职责原则(SRP)详解

[复制链接]
下沙消掉 显示全部楼层 发表于 2021-10-25 19:25:45 |阅读模式 打印 上一主题 下一主题
本文实例报告了PHP面向对象五大原则之单一职责原则(SRP)。分享给大家供大家参考,详细如下:
单一职责原则(Single Pesponsibility Principle, SRP)
单一职责有两个含义: 一个是克制雷同的职责分散到差别的类中, 别一个是克制一个类承担太多职责
为什么要服从SRP呢?
(1)可以减少类之间的耦合
假如减少类之间的耦合,当需求变革时,只修改一个类,从而也就隔离了变革;假如一个类有多个差别职责,它们耦合在一起,当一个职责发生变革时,大概会影响到其他职责。
(2)提高类的复用性
修改电脑比补缀电视机简单多了。主要缘故原由就在于电视机各个部件之间的耦合性太高,而电脑则差别,电脑的内存、硬盘、声卡、网卡、键盘灯等部件都可以很容易地单独拆卸和组装。某个部件坏了,换上新的即可。上面的例子就表现了单一职责的优势。由于使用了单一职责,使得‘组件'可以方便地‘拆卸'和‘组装'。
不服从SRP会影响对类的复用性。当只必要用该类的某一个职责时,由于它和其他的职责耦合在一起,也就很难分离出。
服从SRP在现实代码开发中有没有什么应用?有的。以数据恒久层为例,所谓的数据恒久层主要指的是数据库操纵,当然,还包罗缓存管理等。这时就必要数据恒久层支持多种数据库。应该怎么做?界说多个数据库操纵类?想法已经很靠近了,再进一步,就是使用工厂模式。
工厂模式(Faction)答应你在代码实行时实例化对象。它之以是被称为工厂模式是由于它负责‘生产对象'。以数据库为例,工厂必要的就是根据差别的参数,天生差别的实例化对象。最简单的工厂就是根据传入的类型名实例化对象,如传入MySQL,就调用MySQL类并实例化,假如是SQLite,则调用 SQLite的类并实例化,以致还可以处置惩罚TXT、Execl等‘类数据库'。
工厂类也就是这样的一个类,它只负责生产对象,而不负责对象的详细内容。
以下是示例
界说一个适配器的接口
  1. interface Db_Adpater
  2. {
  3.   /**
  4.    * 数据库连接
  5.    * @param $config 数据库配置
  6.    * @return mixed resource
  7.    */
  8.   public function connect($config);
  9.   /**
  10.    * 执行数据库查询
  11.    * @param $query 数据库查询的SQL字符串
  12.    * @param $handle 连接对象
  13.    * @return mixed
  14.    */
  15.   public function query($query,$handle);
  16. }
复制代码
界说一个实现了DB_Adpater接口的MySQL数据库操纵类
  1. class Db_Adapter_Mysql implements Db_Adpater
  2. {
  3.   private $_dbLink;  //数据库连接字符串标识
  4.   /**
  5.    * 数据库连接函数
  6.    * @param $config 数据库配置
  7.    * @return resource
  8.    * @throws Db_Exception
  9.    */
  10.   public function connect($config)
  11.   {
  12.     if($this->_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->prot) ,$config->user, $config->password, true))
  13.     {
  14.       if(@mysql_select_db($config->database, $this->_dbLink))
  15.       {
  16.         if($config->charset)
  17.         {
  18.           mysql_query("SET NAME '{$config->charset}'", $this->_dbLink);
  19.         }
  20.         return $this->_dbLink;
  21.       }
  22.     }
  23.     throw new Db_Exception(@mysql_error($this->_dbLink));
  24.   }
  25.   /**
  26.    * 执行数据库查询
  27.    * @param $query 数据库查询SQL字符串
  28.    * @param $handle 连接对象
  29.    * @return resource
  30.    */
  31.   public function query($query,$handle)
  32.   {
  33.     if($resource = @mysql_query($query,$handle))
  34.       return $resource;
  35.   }
  36. }
复制代码
界说一个实现了DB_Adpater接口的SQLite数据库操纵类
  1. class Db_Adapter_sqlite implements Db_Adpater
  2. {
  3.   private $_dbLink;  //数据库连接字符串标识
  4.   public function connect($config)
  5.   {
  6.     if($this->_dbLink = sqlite_open($config->file, 0666, $error))
  7.     {
  8.       return $this->_dbLink;
  9.     }
  10.     throw new Db_Exception($error);
  11.   }
  12.   public function query($query, $handle)
  13.   {
  14.     if($resource = @sqlite_query($query,$handle))
  15.     {
  16.       return $resource;
  17.     }
  18.   }
  19. }
复制代码
现在假如必要一个数据库操纵的方法怎么做,只需界说一个工厂类,根据传入差别的天生必要的类即可
  1. class sqlFactory
  2. {
  3.   public static function factory($type)
  4.   {
  5.     if(include_once 'Drivers/' . $type . '.php')
  6.     {
  7.       $classname = 'Db_Adapter_'.$type;
  8.       return new $classname;
  9.     }
  10.     else
  11.       throw new Exception('Driver not found');
  12.   }
  13. }
复制代码
调用时,就可以这么写
  1. $db = sqlFactory::factory('MySQL');
  2. $db = sqlFactory::factory('SQLite');
复制代码
我们把创建数据库毗连这块程序单独拿出来,程序中的CURD就不消关心什么数据库了,只要按照规范使用对应的方法即可。
工厂方法让详细的对象解脱出来,使其不再依赖详细的类,而是抽象。
筹划模式里面的命令模式也是SRP的表现,命令模式分离“命令的哀求者”和“命令的实现者”方面的职责。举一个很好理解的例子,就是你去餐馆订餐用饭,餐馆存在顾客、服务员、厨师三个角色。作为顾客,你要列出菜单,传给服务员,由服务员通知厨师去实现。作为服务员,只必要调用准备饭菜这个方法(对厨师喊“该炒菜了”),厨师听到要炒菜的哀求,就立即去做饭。在这里,命令的哀求和实现就完成相识耦。
模仿这个过程,起首界说厨师角色,厨师举行现实做饭、烧汤的工作。
以下是示例
  1. /**
  2. * 厨师类,命令接受者与执行者
  3. * Class cook
  4. */
  5. class cook
  6. {
  7.   public function meal()
  8.   {
  9.     echo '番茄炒鸡蛋',PHP_EOL;
  10.   }
  11.   public function drink()
  12.   {
  13.     echo '紫菜蛋花汤',PHP_EOL;
  14.   }
  15.   public function ok()
  16.   {
  17.     echo '完毕',PHP_EOL;
  18.   }
  19. }
  20. //然后是命令接口
  21. interface Command
  22. {
  23.   public function execute();
  24. }
复制代码
轮到服务员进场,服务员是命令的传送者,通常你到饭馆用饭都是叫服务员吧,不能直接叫厨师,一般都是叫“服务员,给我来盘番茄炒西红柿”。以是,服务员是顾客和厨师之间的命令沟通都。
  1. class MealCommand implements Command
  2. {
  3.   private $cook;
  4.   //绑定命令接受者
  5.   public function __construct(cook $cook)
  6.   {
  7.     $this->cook = $cook;
  8.   }
  9.   public function execute()
  10.   {
  11.     $this->cook->meal();//把消息传给厨师,让厨师做饭,下同
  12.   }
  13. }
  14. class DrinkCommand implements Command
  15. {
  16.   private $cook;
  17.   //绑定命令接受者
  18.   public function __construct(cook $cook)
  19.   {
  20.     $this->cook = $cook;
  21.   }
  22.   public function execute()
  23.   {
  24.     $this->cook->drink();
  25.   }
  26. }
复制代码
现在顾客可以按照菜单叫服务员了
  1. class cookControl
  2. {
  3.   private $mealcommand;
  4.   private $drinkcommand;
  5.   //将命令发送者绑定以命令接收器上面来
  6.   public function addCommand(Command $mealcommand, Command $drinkcommand)
  7.   {
  8.     $this->mealcommand = $mealcommand;
  9.     $this->drinkcommand = $drinkcommand;
  10.   }
  11.   public function callmeal()
  12.   {
  13.     $this->mealcommand->execute();
  14.   }
  15.   public function calldrink()
  16.   {
  17.     $this->drinkcommand->execute();
  18.   }
  19. }
复制代码
好了,现在完成整个过程
  1. $control = new cookControl;
  2. $cook = new cook;
  3. $mealcommand = new MealCommand($cook);
  4. $drinkcommand = new DrinkCommand($cook);
  5. $control->addCommand($mealcommand,$drinkcommand);
  6. $control->callmeal();
  7. $control->calldrink();
复制代码
从上面的例子可以看出,原来筹划模式并非纯理论的东西,而是泉源于现实生活,就连平常的餐馆老板都懂筹划模式这门看似高深的学问。其实,在经济和管理运动中对流程的优化就是对各种筹划模式的摸索和实践。以是,筹划模式并非盘算机编程中的专利。究竟上,筹划模式的劈头并不是盘算机,而是源于建筑学。
在筹划模式方面,不仅以上这两种表现了SRP,还有别的(好比署理模式)也表现了SRP。SRP不只是对类筹划有意义,对以模块、子体系为单位的体系架构筹划同样有意义。
模块、子体系也应该仅有一个引起它变革的缘故原由,如MVC所倡导的各个层之间的相互分离就是SRP在体系总体筹划中的应用。
SRP是最简单的原则之一,也是最难做好的原则之一。我们会很自然地将职责毗连在一起。找到并且分离这些职责是软件筹划必要到达的目的
一些简单的应用遵照的做法如下:
根据业务流程,把业务对象提炼出来。假如业务的流程的链路太复杂,就把这个业务对象分离为多个单一业务对象。当业务链尺度化后,对业务对象的内部环境做进一步处置惩罚,把第一次尺度化视为最高层抽象,第二次视为次高层抽象,以此类推,直到“恰到好处”的筹划层次
职责的分类必要留意。有业务职责,还要有脱离业务的抽象职责,从认识业务到抽象算法是一个层层递进的过程。就好比命令模式中的顾客,服务员和厨师的职责,作为老板(即筹划师)的你必要规划好各自的职责范围,即要防止越俎代庖,也要防止相互推诿。
更多关于PHP相干内容感爱好的读者可查察本站专题:《php面向对象程序筹划入门教程》、《PHP数组(Array)操纵本领大全》、《PHP基本语法入门教程》、《PHP运算与运算符用法总结》、《php字符串(string)用法总结》、《php+mysql数据库操纵入门教程》及《php常见数据库操纵本领汇总》
盼望本文所述对大家PHP程序筹划有所帮助。

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作