ホームページ > バックエンド開発 > PHPチュートリアル > PHP オブジェクト指向設計 (SOLID) の 5 つの原則のまとめ

PHP オブジェクト指向設計 (SOLID) の 5 つの原則のまとめ

不言
リリース: 2023-04-03 07:26:02
オリジナル
2215 人が閲覧しました

この記事では、主に PHP オブジェクト指向設計 (SOLID) の 5 つの原則の概要を紹介しますが、これは一定の参考価値があります。ここで共有します。必要な友人は参考にしてください。

PHP設計原則 これを整理するには、「PHP コア テクノロジとベスト プラクティス」、「アジャイル開発の原則、パターン、およびプラクティス」の記事「PHP オブジェクト指向設計の 5 つの原則」、「デザイン パターンの原則」を参照してください。SOLID

単一責任原則、SRP)

定義/機能
  • クラス変更の理由は 1 つだけです

  • クラスには、責任は 1 つ (責任: 変更の理由)

  • 同じ責任が異なるクラスに分散されたり、機能が重複したりしないようにします

問題
  • クラスの責任が多すぎます。また、複数の責任が相互に依存しています。1 つの責任を変更すると、このクラスが他の責任を遂行する能力に影響します。クラス変更の原因が発生すると、クラスは変更されます。破壊

SPR 原則に従うことの利点
  • クラス間の結合を減らす: 要件が変化したとき、 1 つのクラスのみを変更することで、そのクラスに起因する他の責任への変更の影響を分離します。

  • クラスの再利用性を向上します: オンデマンドでの参照、1 つのクラスが責任を負います1 つの責任、要件に対して、変更には対応するクラスを変更するか、特定の責任を追加するだけで済みます。

  • クラスの複雑さを軽減します: 単一の責任、分散機能 1 つのクラスを削減します。複数の責任クラスへの複雑さ

コード例
class ParseText
{
    private $content;
    
    public function decodeText(String $content)
    {
        // TODO: decode content
    }
    
    public function saveText()
    {
        // TODO:: save $this->content;
    }
}
/*
问题思考:
解析的文本类型会有多种-html、xml、json
保存的文本也会有多种途径-redis、mysql、file
客户端只需要解析文本时必须会引入saveText不需要的方法
两个职责之间没有强烈的依赖关系存在
任意职责需求变化都需要更改这个类
*/

/*
符合SRP的设计
职责拆分
*/

class Decoder
{
    private $content;
    
    public function decodeText(String $content)
    {
    // TODO: decode content
    }
    
    public function getText()
    {
        return $this->content;
    }
}

class Store
{
    public function save($content)
    {
        // TODE: save
    }
}
ログイン後にコピー
要約

ソフトウェア設計で行うことの多くは、責任を発見し、責任間の関係を合理的に分離することです。アプリケーションへの変更が常に複数の責任に同時に影響する場合、責任を分離する必要はありません。

インターフェイス分離原則 ISP

問題

アプリケーションを設計するとき、クラスのインターフェイスがまとまっていません。さまざまなクライアントにはいくつかの集中化された機能しか含まれていませんが、システムはクライアントにモジュール内のすべてのメソッドを実装することを強制し、いくつかのダムメソッドも作成します。このようなインターフェイスは、ファット インターフェイスまたはインターフェイス汚染になります。このようなインターフェイスは、システムに不適切な動作を導入し、リソースを浪費し、他のクライアント プログラムに影響を与え、結合を強化します。

ISP 定義/機能

  • クライアントは、必要のないメソッド/関数に依存することを強制されるべきではありません

  • ##クラスに対するクラスの依存関係は、最小のインターフェイスに基づく必要があります。

  • インターフェイスの実装クラスは単一責任原則としてのみ提示する必要があります

  • ##ISP 原則に従う利点
    ファット インターフェイスは分離され、インターフェイスの各グループは、クライアント プログラムの特定のグループにサービスを提供する特定の機能を提供します。
  • インターフェイスの 1 つのグループに対する変更は、影響を与えません/わずかに影響します他のインターフェイス/インターフェイスの純度を保証するためのクライアント プログラム
  • 解決策

    ファット インターフェイスは複数のクライアント固有のインターフェイス/複数に分解されます。インターフェイスは分離され、継承されます。
  • #委任分離インターフェイスを使用すると、2 つのオブジェクトが同じリクエストの処理に参加し、リクエストを受け入れたオブジェクトがリクエストを別のオブジェクトに委任して処理します
  • コード例
/*
* 公告接口
*/
interface Employee
{
    public function startWork();
    public function endWork();
}

/*
* 定义特定客户端接口
*/
interface Coder
{
    public function writeCode();
}

interface Ui
{
    public function designPage();
}

class CoderClient implements Employee, Coder
{
    public function startWork()
    {
        //TODO:: start work time
    }
    public function endWork()
    {
        //TODO:: end work time
    }
    
    public function writeCode()
    {
        //TODO:: start write code
        return 'hellow world';
    }
}
$c = new CoderClient();
echo $c->writeCode();
ログイン後にコピー
概要
ファット クラスは、クライアント プログラム間に異常で有害な結合関係を引き起こす可能性があります。シック クライアントを複数のクライアント固有のインターフェイスに分解することで、クライアントは実際に呼び出すメソッドに強く依存し、クライアントと呼び出さないメソッドの間の依存関係を切り離します。インターフェイスの分離は小さく、頻繁に行わないでください。
SRP と ISP の比較

どちらもソフトウェア設計における依存関係の原則を解決します
  • SRP は責任の分割に重点を置いています, 主に Constraint クラスは実際にはインターフェイスとメソッドであり、プログラム内の詳細と実装です。 ISP はインターフェイスの分離に重点を置き、インターフェイスを制限し、よりマクロな観点からインターフェイスの設計を抽象化します
  • オープンクローズ原則 OCP
問題

ソフトウェア システムの規模が拡大し続けるにつれて、システムの保守と変更の複雑さは増加し続けています。システムの一部の変更は、他のモジュールに影響を与えることがよくあります。 OCP 原則を正しく適用すると、このような問題を解決できます。
定義/特性

モジュールは動作の拡張という点ではオープンであり、変更可能性という点ではクローズである必要があります
  • ##フォローOCP の利点

モジュールの動作は拡張可能で、既存のモジュールの動作/機能を簡単に拡張できます
  • モジュールの拡張動作は既存のシステム/モジュールにほとんど影響を与えません

  • コード例

    /*
    * 定义有固定行为的抽象接口
    */
    interface Process
    {
        public function action(String $content);
    }
    
    /*
    * 继承抽象接口,扩展不同的行为
    */
    class WriteToCache implements Process
    {
        public function action(String $content)
        {
            return 'write content to cache: '.$content;
        }
    }
    
    class ParseText
    {
        private $content;
        public function decodeText($content)
        {
            $this->content = $content;
        }
        
        public function addAction(Process $process)
        {
            if ($process instanceof Process) {
                return $process->action($this->content);    
            }
        }
    }
    
    $p = new ParseText();
    $p->decodeText('content');
    echo $p->addAction(new WriteToCache());
    ログイン後にコピー
    概要
OCP の核となる考え方はインターフェイスの抽象化ですプログラミング、抽象化は比較的安定しています。クラスを固定の抽象化に依存させたり、オブジェクト指向の継承やポリモーフィズムによって抽象化を継承させたり、クラスのメソッドや固有の動作を上書きしたりすることで、新たな拡張メソッド/関数を考えて拡張を実現します。

里氏替换原则(Liskov Substitution Principle LSP)

问题

面向对象中大量的继承关系十分普遍和简单,这种继承规则是什么,最佳的继承层次的规则又是什么,怎样优雅的设计继承关系,子类能正确的对基类中的某些方法进行重新,这是LSP原则所要处理的问题。

定义/特性
  • 子类必须能够替换掉他们的基类型:任何出现基类的地方都可以替换成子类并且客户端程序不会改变基类行为或者出现异常和错误,反之不行。

  • 客户端程序只应该使用子类的抽象父类,这样可以实现动态绑定(php多态)

违反LSP原则

假设一个函数a,他的参数引用一个基类b,c是b的派生类,如果将c的对象作为b类型传递给a,会导致a出现错误的行为,那没c就违法了LSP原则。

/*
* 基类
*/
class Computer
{
    public function action($a, $b)
    {
        return $a+$b;
    }
}
/*
* 子类复习了父类方法,改变了action 的行为
* 违反了LSP原则
*/
class Client extends Computer
{
    public function action($a, $b)
    {
        return $a-$b;
    }  
}

function run(Computer $computer, $a, $b) {
    return $computer->action($a, $b);
}

echo run((new Client()), 3, 5);
ログイン後にコピー
总结

LSP是OCP得以应用的最主要的原则之一,正是因为子类性的可替换行是的基类类型在无需修改的情况下扩展功能。

依赖倒置原则(Depend Inversion Principle DIP)

问题

软件开发设计中,总是倾向于创建一些高层模块依赖底层模块,底层模块更改时直接影响到高层模块,从而迫使他们改变。DIP原则描述了高层次模块怎样调用低层次模块。

定义/特性
  • 高层模块不应该依赖与底层模块,二者都应该依赖于抽象

  • 抽象不应该依赖与细节,细节应该依赖于抽象

代码示例
interface Arithmetic
{
    //public function sub($a, $b);
}

class Client
{
    
    public function computer(Arithmetic $arithmetic, $a, $b)
    {
        return $arithmetic->add($a, $b);
    }
}

class Addition implements Arithmetic
{
    public function add($a, $b)
    {
        return $a + $b;
    }
}

$c = new Client();
echo $c->computer(new Addition(), 2, 3);

/*
client 高层类 依赖于Arithmetic,Addition底层实现细节类实现Arithmetic接口,达到二者依赖于抽象接口的DIP设计原则
*/
ログイン後にコピー
总结

DIP原则就是每个高层次模块定义一个它所需服务的接口声明,低层次模块实现这个接口。每个高层次类通过该抽象接口使用服务。

思考

面向对象软件开发中合理的遵循设计原则可以更好的设计代码,减少不必要的错误,提高程序的可维护性,可扩展性和稳定性。

  • 单一职责(SRP)如何正确的划分职责,类的职责单一提高代码复用性,降低耦合性

  • 接口隔离(OCP)合理划分接口功能,保证接口的专一性,纯洁性,减少依赖关系

  • 里氏替换(LSP)合理利用类的继承体系,保证真确的继承关系不被破坏

  • 依赖倒置(DIP)抽象接口编程由于抽象具体实现

  • 开放封闭(OCP)面向对象编程终极目标所达到的结果,类/模块/系统的功能行为可扩展,内部更改性是封闭的

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

对LNMP的运维追踪

以上がPHP オブジェクト指向設計 (SOLID) の 5 つの原則のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート