中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP中職責原則SRP的示例分析

發布時間:2021-08-06 09:57:32 來源:億速云 閱讀:170 作者:小新 欄目:開發技術

這篇文章主要介紹了PHP中職責原則SRP的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

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

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

為什么要遵守SRP呢?

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

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

(2)提高類的復用性

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

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

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

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

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

以下是示例

定義一個適配器的接口

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數據庫操作類

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數據庫操作類

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;
    }
  }
}

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

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');
  }
}

調用時,就可以這么寫

$db = sqlFactory::factory('MySQL');
$db = sqlFactory::factory('SQLite');

我們把創建數據庫連接這塊程序單獨拿出來,程序中的CURD就不用關心什么數據庫了,只要按照規范使用對應的方法即可。

工廠方法讓具體的對象解脫出來,使其不再依賴具體的類,而是抽象。

設計模式里面的命令模式也是SRP的體現,命令模式分離“命令的請求者”和“命令的實現者”方面的職責。舉一個很好理解的例子,就是你去餐館訂餐吃飯,餐館存在顧客、服務員、廚師三個角色。作為顧客,你要列出菜單,傳給服務員,由服務員通知廚師去實現。作為服務員,只需要調用準備飯菜這個方法(對廚師喊“該炒菜了”),廚師聽到要炒菜的請求,就立即去做飯。在這里,命令的請求和實現就完成了解耦。

模擬這個過程,首先定義廚師角色,廚師進行實際做飯、燒湯的工作。

以下是示例

/**
 * 廚師類,命令接受者與執行者
 * 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();
}

輪到服務員出場,服務員是命令的傳送者,通常你到飯館吃飯都是叫服務員吧,不能直接叫廚師,一般都是叫“服務員,給我來盤番茄炒西紅柿”。所以,服務員是顧客和廚師之間的命令溝通都。

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

現在顧客可以按照菜單叫服務員了

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

好了,現在完成整個過程

$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中職責原則SRP的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI

四子王旗| 许昌县| 筠连县| 台北市| 神木县| 无极县| 高邑县| 隆子县| 深圳市| 杭锦旗| 伊宁县| 岗巴县| 会泽县| 安仁县| 莫力| 宁波市| 鲁甸县| 怀安县| 赞皇县| 玉环县| 洛阳市| 黄冈市| 滨州市| 开平市| 平乐县| 舞阳县| 偃师市| 锡林浩特市| 聂荣县| 西林县| 海门市| 庄河市| 吉木乃县| 宜良县| 梁山县| 凌源市| 尚义县| 宁蒗| 五大连池市| 婺源县| 高雄县|