ホームページ  >  記事  >  バックエンド開発  >  PHP 単一責任原則 (SRP) のユースケース分析

PHP 単一責任原則 (SRP) のユースケース分析

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-17 10:56:111648ブラウズ

今回は、PHP 単一責任原則 (SRP) のユースケースの分析をお届けします。PHP 単一責任原則 (SRP) を使用する際の注意点は何ですか? 以下は実際のケースです。

単一責任原則 (SRP)

単一責任には 2 つの意味があります: 1 つは同じ責任が異なるクラスに分散されることを避けること、もう 1 つは 1 つのクラスがあまりにも多くの責任を引き受けることを避けることです

なぜ遵守する必要があるのかSRP を使用すると?

(1) クラス間の結合を減らすことができます

クラス間の結合を減らすと、要件が変更されたときに 1 つのクラスのみが変更されるため、クラスが複数ある場合は変更が分離されます。 1 つの責任が変化すると、他の責任が影響を受ける可能性があります。

(2) クラスの再利用性を向上させる

コンピューターを改造するのは、テレビを修理するよりもはるかに簡単です。主な理由は、テレビのさまざまなコンポーネント間の結合が高すぎることですが、コンピューターとは異なり、メモリー、ハードディスク、サウンド カード、ネットワーク カード、キーボード ライトなどのコンポーネントは簡単に分解して組み立てることができます。別々に。部品が壊れた場合は、新しいものと交換するだけです。上の例は、単一責任の利点を示しています。単一責任を使用するため、「コンポーネント」は簡単に「分解」および「組み立て」できます。

SRP に準拠しない場合は、クラスの再利用性に影響します。クラスの特定の責任だけを使用する必要がある場合、それは他の責任と結合しているため、分離することが困難です。

実際のコード開発において SRP に準拠する応用はありますか?いくつかの。データ永続層を例に挙げると、いわゆるデータ永続層とは主に データベース操作 を指し、もちろんキャッシュ管理なども指します。現時点では、データ永続層は複数のデータベースをサポートする必要があります。何をすべきでしょうか?複数のデータベース操作クラスを定義しますか?このアイデアはすでにかなり近づいており、次のステップはファクトリー パターンを使用することです。

ファクトリ パターン (ファクション) を使用すると、コードの実行時にオブジェクトをインスタンス化できます。 「オブジェクトの生成」を担当するため、ファクトリー パターンと呼ばれます。データベースを例にとると、ファクトリで必要なのは、さまざまなパラメータに基づいてさまざまなインスタンス化されたオブジェクトを生成することです。最も単純なファクトリは、渡された型名に基づいてオブジェクトをインスタンス化することです。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');
  }
}

データベースを作成します

このプログラムを別途作成しますプログラム内の CURD はデータベースを気にする必要はなく、仕様に従って対応するメソッドを使用するだけです。

ファクトリ メソッドは具象オブジェクトを解放し、具象クラスではなく抽象化に依存するようにします。

デザインパターンのコマンドパターンもSRPの具現化です。 コマンドパターンは「

コマンドの要求者

」と「

コマンドの実装者」の責任を分離します。わかりやすい例を挙げると、レストランに食事を注文する場合、レストランには顧客、ウェイター、シェフという 3 つの役割があります。顧客はメニューをリストアップしてウェイターに渡し、ウェイターがシェフにそれを実行するよう指示する必要があります。ウェイターとしては、調理方法をコールするだけで済みます(「炒める時間です」とシェフに呼びかけます)。シェフは炒め物のリクエストを聞いたら、すぐに調理します。ここでは、コマンドのリクエストと実装は完全に分離されています。 このプロセスをシミュレートするには、まずシェフの役割を定義し、シェフが実際に料理とスープを作る作業を行います。

以下は一例です

rreee

それはウェイターの番です。通常、レストランに食事に行くとき、あなたはウェイターに直接電話することはできません。ウェイター、フライドトマトの皿を持ってきてください。」したがって、ウェイターは顧客とシェフの間の注文の伝達者です。

そうです

お客様はメニューに従ってウェイターを呼ぶことができるようになりました

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中文网其它相关文章!

推荐阅读:

PHP里氏替换案例详解

Bootstrap+PHP实现多图上传步骤详解

以上がPHP 単一責任原則 (SRP) のユースケース分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。