首頁 後端開發 php教程 詳解PHP物件導向五大原則之單一職責原則

詳解PHP物件導向五大原則之單一職責原則

Apr 11, 2018 am 10:52 AM
php

本文實例講述了PHP物件導向五大原則之單一職責原則(SRP)。分享給大家供大家參考,具體如下:

單一職責原則(Single Pesponsibility Principle, SRP)

單一職責有兩個意義: 一個是避免相同的職責分散到不同的類別中, 別一個是避免一個類別承擔太多職責

為什麼要遵守SRP呢?

(1)可以減少類別之間的耦合

如果減少類別之間的耦合,當需求變化時,只修改一個類,從而也就隔離了變化;如果一個類別有多個不同職責,它們耦合在一起,當一個職責發生變化時,可能會影響到其他職責。

(2)提高類別的複用性

修改電腦比修理電視機簡單多了。主要原因就在於電視機各個部件之間的耦合性太高,而電腦則不同,電腦的內存、硬碟、音效卡、網卡、鍵盤燈等部件都可以輕鬆地單獨拆卸和組裝。某個部件壞了,換上新的即可。上面的例子就體現了單一職責的優勢。由於使用了單一職責,使得‘組件'可以方便地‘拆卸’和‘組裝’。

不遵守SRP會影響對類別的複用性。當只需要用該類別的某一個職責時,由於它和其他的職責耦合在一起,也就很難分離出。

遵守SRP在實際程式碼開發上有沒有什麼應用?有的。以資料持久層為例,所謂的資料持久層主要指的是資料庫操作,當然,還包括快取管理等。這時就需要資料持久層支援多種資料庫。應該怎麼做?定義多個資料庫操作類別?想法已經很接近了,再進一步,就是使用工廠模式。

工廠模式(Faction)允許你在程式碼執行時實例化物件。它之所以被稱為工廠模式是因為它負責『生產對象』。以資料庫為例,工廠需要的就是根據不同的參數,產生不同的實例化物件。最簡單的工廠就是根據傳入的型別名稱實例化對象,如傳入MySQL,就呼叫MySQL類別並實例化,如果是SQLite,則呼叫SQLite的類別並實例化,甚至還可以處理TXT、Execl等'類資料庫'。

工廠類也就是這樣的一個類,它只負責生產對象,而不負責對象的具體內容。

以下是範例

定義一個適配器的介面

  1. interface Db_Adpater
    {
      /**
       * 数据库连接
       * @param $config 数据库配置
       * @return mixed resource
       */
      public function connect($config);
      /**
       * 执行数据库查询
       * @param $query 数据库查询的SQL字符串
       * @param $handle 连接对象
       * @return mixed
       */
      public function query($query,$handle);
    }
    登入後複製

定義一個實作了DB_Adpater介面的MySQL資料庫操作類

  1. class Db_Adapter_Mysql implements Db_Adpater
    {
      private $_dbLink;  //数据库连接字符串标识
      /**
       * 数据库连接函数
       * @param $config 数据库配置
       * @return resource
       * @throws Db_Exception
       */
      public function connect($config)
      {
        if($this->_dbLink = @mysql_connect($config->host . (empty($config->port) ? '' : ':' . $config->prot) ,$config->user, $config->password, true))
        {
          if(@mysql_select_db($config->database, $this->_dbLink))
          {
            if($config->charset)
            {
              mysql_query("SET NAME '{$config->charset}'", $this->_dbLink);
            }
            return $this->_dbLink;
          }
        }
        throw new Db_Exception(@mysql_error($this->_dbLink));
      }
      /**
       * 执行数据库查询
       * @param $query 数据库查询SQL字符串
       * @param $handle 连接对象
       * @return resource
       */
      public function query($query,$handle)
      {
        if($resource = @mysql_query($query,$handle))
          return $resource;
      }
    }
    登入後複製

定義一個實作了DB_Adpater介面的SQLite資料庫操作類別

  1. class Db_Adapter_sqlite implements Db_Adpater
    {
      private $_dbLink;  //数据库连接字符串标识
      public function connect($config)
      {
        if($this->_dbLink = sqlite_open($config->file, 0666, $error))
        {
          return $this->_dbLink;
        }
        throw new Db_Exception($error);
      }
      public function query($query, $handle)
      {
        if($resource = @sqlite_query($query,$handle))
        {
          return $resource;
        }
      }
    }
    登入後複製

#現在如果需要一個資料庫操作的方法怎麼做,只需定義一個工廠類,根據傳入不同的生成需要的類即可

  1. #
    class sqlFactory
    {
      public static function factory($type)
      {
        if(include_once 'Drivers/' . $type . '.php')
        {
          $classname = 'Db_Adapter_'.$type;
          return new $classname;
        }
        else
          throw new Exception('Driver not found');
      }
    }
    登入後複製

調用時,就可以這麼寫

  1. $db = sqlFactory::factory('MySQL');
    $db = sqlFactory::factory('SQLite');
    登入後複製

我们把创建数据库连接这块程序单独拿出来,程序中的CURD就不用关心什么数据库了,只要按照规范使用对应的方法即可。

工厂方法让具体的对象解脱出来,使其不再依赖具体的类,而是抽象。

设计模式里面的命令模式也是SRP的体现,命令模式分离“命令的请求者”和“命令的实现者”方面的职责。举一个很好理解的例子,就是你去餐馆订餐吃饭,餐馆存在顾客、服务员、厨师三个角色。作为顾客,你要列出菜单,传给服务员,由服务员通知厨师去实现。作为服务员,只需要调用准备饭菜这个方法(对厨师喊“该炒菜了”),厨师听到要炒菜的请求,就立即去做饭。在这里,命令的请求和实现就完成了解耦。

模拟这个过程,首先定义厨师角色,厨师进行实际做饭、烧汤的工作。

以下是示例

  1. /**
     * 厨师类,命令接受者与执行者
     * Class cook
     */
    class cook
    {
      public function meal()
      {
        echo '番茄炒鸡蛋',PHP_EOL;
      }
      public function drink()
      {
        echo '紫菜蛋花汤',PHP_EOL;
      }
      public function ok()
      {
        echo '完毕',PHP_EOL;
      }
    }
    //然后是命令接口
    interface Command
    {
      public function execute();
    }
    登入後複製

轮到服务员出场,服务员是命令的传送者,通常你到饭馆吃饭都是叫服务员吧,不能直接叫厨师,一般都是叫“服务员,给我来盘番茄炒西红柿”。所以,服务员是顾客和厨师之间的命令沟通都。

  1. class MealCommand implements Command
    {
      private $cook;
      //绑定命令接受者
      public function __construct(cook $cook)
      {
        $this->cook = $cook;
      }
      public function execute()
      {
        $this->cook->meal();//把消息传给厨师,让厨师做饭,下同
      }
    }
    class DrinkCommand implements Command
    {
      private $cook;
      //绑定命令接受者
      public function __construct(cook $cook)
      {
        $this->cook = $cook;
      }
      public function execute()
      {
        $this->cook->drink();
      }
    }
    登入後複製

现在顾客可以按照菜单叫服务员了

  1. class cookControl
    {
      private $mealcommand;
      private $drinkcommand;
      //将命令发送者绑定以命令接收器上面来
      public function addCommand(Command $mealcommand, Command $drinkcommand)
      {
        $this->mealcommand = $mealcommand;
        $this->drinkcommand = $drinkcommand;
      }
      public function callmeal()
      {
        $this->mealcommand->execute();
      }
      public function calldrink()
      {
        $this->drinkcommand->execute();
      }
    }
    登入後複製

好了,现在完成整个过程

  1. $control = new cookControl;
    $cook = new cook;
    $mealcommand = new MealCommand($cook);
    $drinkcommand = new DrinkCommand($cook);
    $control->addCommand($mealcommand,$drinkcommand);
    $control->callmeal();
    $control->calldrink();
    登入後複製

从上面的例子可以看出,原来设计模式并非纯理论的东西,而是来源于实际生活,就连普通的餐馆老板都懂设计模式这门看似高深的学问。其实,在经济和管理活动中对流程的优化就是对各种设计模式的摸索和实践。所以,设计模式并非计算机编程中的专利。事实上,设计模式的起源并不是计算机,而是源于建筑学。

在设计模式方面,不仅以上这两种体现了SRP,还有别的(比如代理模式)也体现了SRP。SRP不只是对类设计有意义,对以模块、子系统为单位的系统架构设计同样有意义。

模块、子系统也应该仅有一个引起它变化的原因,如MVC所倡导的各个层之间的相互分离就是SRP在系统总体设计中的应用。

SRP是最简单的原则之一,也是最难做好的原则之一。我们会很自然地将职责连接在一起。找到并且分离这些职责是软件设计需要达到的目的

一些简单的应用遵循的做法如下:

根据业务流程,把业务对象提炼出来。如果业务的流程的链路太复杂,就把这个业务对象分离为多个单一业务对象。当业务链标准化后,对业务对象的内部情况做进一步处理,把第一次标准化视为最高层抽象,第二次视为次高层抽象,以此类推,直到“恰如其分”的设计层次

职责的分类需要注意。有业务职责,还要有脱离业务的抽象职责,从认识业务到抽象算法是一个层层递进的过程。就好比命令模式中的顾客,服务员和厨师的职责,作为老板(即设计师)的你需要规划好各自的职责范围,即要防止越俎代庖,也要防止互相推诿。

以上是詳解PHP物件導向五大原則之單一職責原則的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 適用於 Ubuntu 和 Debian 的 PHP 8.4 安裝和升級指南 Dec 24, 2024 pm 04:42 PM

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 如何設定 Visual Studio Code (VS Code) 進行 PHP 開發 Dec 20, 2024 am 11:31 AM

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

我後悔之前不知道的 7 個 PHP 函數 我後悔之前不知道的 7 個 PHP 函數 Nov 13, 2024 am 09:42 AM

如果您是經驗豐富的PHP 開發人員,您可能會感覺您已經在那裡並且已經完成了。操作

您如何在PHP中解析和處理HTML/XML? 您如何在PHP中解析和處理HTML/XML? Feb 07, 2025 am 11:57 AM

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

See all articles