検索

The Liskov Substitution Principle

コアポイント

  • リスコフ代替原理(LSP)は、クライアントコードで契約を破ることなく、サブクラスが基本クラスの抽象化を置き換えることができるようにするオブジェクト指向プログラミングの重要な概念です。システム設計の整合性を維持し、コードの再利用性に不可欠です。
  • サブクラスの上昇する場合、特定の要件を満たす必要があります。
  • LSP違反は、追跡が困難な止められない動作とエラーにつながる可能性があります。また、サブクラスがスーパークラスを置き換えることができるという仮定はもはや真実ではないため、コードの維持と拡張が難しくなります。
  • メソッド書き換えは、常にLSPに違反するとは限りません。ただし、書き換えられたメソッドが、スーパークラス契約では予想されない方法で元の方法の動作を変更すると、LSPに違反します。
  • コードがLSPに準拠することを確認するために、基本クラスの関数を拡張するのではなく、拡張するのではなく)サブクラスを作成することをお勧めします。さらに、継承の代わりに構成を使用してインターフェイスを実装することは、LSPによって課される条件の抽象化を破ることなく、派生クラスを作成するのに役立ちます。

架空のシーン:ハッカーとマトリックス

次の会話は、マトリックスの三部作のカットシーンから来ています:

メルフェウス:ネオ、私は今マトリックスにいます。この悪いニュースをお知らせしますが、エージェント追跡PHPプログラムには簡単な更新が必要です。現在、PDOのQuery()メソッド(文字列付き)を使用して、データベースからすべてのマトリックスエージェントの状態を取得していますが、代わりにプリプロセシングクエリを使用する必要があります。

neo:いいですね、モルフェウス。プログラムのコピーを入手できますか?

メルフェス:問題ありません。リポジトリをクローンして、agentmapper.phpおよびindex.phpファイルをチェックしてください。

(NEOはいくつかのgitコマンドを実行すると、彼の前に次のコードが表示されます)

nio:モルフェウス、文書を手に入れました。 PDOをサブクラス化し、Query()メソッドをオーバーライドして、前処理クエリを使用できるようにします。私の超大国のため、私はこの仕事を非常に迅速に終えることができるはずです。冷静さを保つ。
<?php namespace ModelMapper;

class AgentMapper
{
    protected $_adapter;
    protected $_table = "agents";

    public function __construct(PDO $adapter) {
        $this->_adapter = $adapter;
    }

    public function findAll() {
        try {
            return $this->_adapter->query("SELECT * FROM " . $this->_table, PDO::FETCH_OBJ);
        }
        catch (Exception $e) {
            return array();
        }
    }   
}
<?php use ModelMapperAgentMapper;

// 一个 PSR-0 兼容的类加载器
require_once __DIR__ . "/Autoloader.php";

$autoloader = new Autoloader();
$autoloader->register();

$adapter = new PDO("mysql:dbname=Nebuchadnezzar", "morpheus", "aa26d7c557296a4e8d49b42c8615233a3443036d");

$agentMapper = new AgentMapper($adapter);
$agents = $agentMapper->findAll();

foreach ($agents as $agent) {
    echo "Name: " . $agent->name .  " - Status: " . $agent->status . "<br>";
}

(コンピューターのキーボードの音が空中に響き渡ります)nio:モルフェウス、サブクラスはテストの準備ができています。いつでもチェックしてください。

(マーフィーズはラップトップで迅速に検索し、次のクラスを見ました)

メルフェス:アダプターはよく見えます。エージェントマッパーがマトリックスを通過するアクティブなエージェントを追跡できるかどうかを確認するために、すぐに試してみます。私に頑張ってください。

(Murphysはしばらくheして、以前のindex.phpファイルを実行して、今回はNeoの傑作PdoAdapterクラスを使用しています。 メルフェウス:ネオ、あなたは「救い主」だと思います!しかし、私の顔にはひどい致命的な誤りがあり、ニュースは次のとおりでした:

<?php namespace LibraryDatabase;

class PdoAdapter extends PDO
{
    protected $_statement;

    public function __construct($dsn, $username = null, $password = null, array $driverOptions = array()) {
        // 检查是否传递了有效的 DSN
        if (!is_string($dsn) || empty($dsn)) {
            throw new InvalidArgumentException("The DSN must be a non-empty string.");
        }
        try {
            // 尝试创建一个有效的 PDO 对象并设置一些属性。
            parent::__construct($dsn, $username, $password, $driverOptions);
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
            $this->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }

    public function query($sql, array $parameters = array())
    {
        try {
           $this->_statement = $this->prepare($sql);
           $this->_statement->execute($parameters);
           return $this->_statement->fetchAll(PDO::FETCH_OBJ);        
        }
        catch (PDOException $e) {
            throw new RunTimeException($e->getMessage());
        }
    }
}

(別の叫び声)

neo:何が問題なのですか? !何が悪かったの? ! (その他の叫び声)

メルフェス:私は本当に知りません。ああ、エージェント・スミスは今私を捕まえに来ています! (コミュニケーションが突然中断されました。長い沈黙が会話を終了し、モルフェウスが不意を突かれ、エージェントスミスによって重傷を負ったことを示唆しました。

lspは、怠zyで愚かなプログラマーを表していません

言うまでもなく、上記の対話は架空のものですが、問題は間違いなく真実です。ネオが、かつて彼がかつて有名だったハッカーのようにリスコフ代替原則(LSP)について1つか2つの知識しか学んだ場合、エージェント・スミスはすぐに追跡できました。最も重要なことは、モルフェウスはエージェントの悪意から保護されていることです。それは彼にとってとても残念でした。ただし、多くの場合、PHP開発者は、NEOの以前の意見とほぼ同じLSPについて考えています。LSPは、実際にはほとんど適用されない純粋な理論的原則に他なりません。しかし、彼らは間違った方法で行きました。 LSPの正式な定義は見事ですが(私を含む)、その中心は、同じ契約を使用する基本クラスの抽象化と子孫が非常に異なって振る舞う不明確に定義されたクラスの階層を避けることです。簡単に言えば、LSPは、サブクラスでメソッドを書き換えるとき、次の要件を満たす必要があることを規定しています。

その署名は、親クラスの署名と一致する必要があります

    前提条件(受け入れるもの)は同じか弱いか
  1. 彼らの事後条件(予想されること)は同じか強いか
  2. 例外(ある場合)は、親クラスによってスローされた例外タイプと同じでなければなりません
  3. さて、上記のリストをもう一度読んでください(心配しないでください、待ちます)。これが理にかなっている理由を理解したいと思います。例に戻ると、Neoの致命的なエラーは、メソッドの署名を同じに保つことができず、クライアントコードと契約を破ります。この問題を解決するために、エージェントマッパーのfindall()メソッドは、以下に示すように、いくつかの条件付きステートメント(明らかなコード臭)で書き直すことができます。
    <?php namespace ModelMapper;
    
    class AgentMapper
    {
        protected $_adapter;
        protected $_table = "agents";
    
        public function __construct(PDO $adapter) {
            $this->_adapter = $adapter;
        }
    
        public function findAll() {
            try {
                return $this->_adapter->query("SELECT * FROM " . $this->_table, PDO::FETCH_OBJ);
            }
            catch (Exception $e) {
                return array();
            }
        }   
    }

    気分が良い場合は、リファクタリング方法を試してみると、ネイティブPDOオブジェクトを使用するか、PDOアダプターのインスタンスを使用するかにかかわらず、うまく機能します。私はこれが荒いように聞こえることを知っていますが、それは迅速かつ簡単な修正であり、開閉の原則に露骨に違反しています。一方、AdapterのQuery()メソッドは、親クラスの書き換えの署名に一致するようにリファクタリングできます。しかし、そうすることで、LSPによって記載されている他のすべての条件も満たされるべきです。要するに、これは、メソッドの書き換えは注意して行うべきであり、非常に強い理由でのみ行うことができることを意味します。多くのユースケースでは、インターフェイスを使用できないと仮定すると、基本クラスの機能を(オーバーライドするのではなく)拡張するだけのサブクラスを作成する方が良いです。 NEOのPDOアダプターの場合、このアプローチは完全に機能し、クライアントコードをどのレベルでも破ることはありません。先ほど言ったように、インターフェイスの実装を活用するより効率的な、しかしより根本的なソリューションがあります。以前のPDOアダプターは継承を通じて作成され、LSPの教訓に間違いなく違反しましたが、実際には、エージェントマッパークラスが元々設計された方法から欠点があります。実際、インターフェイス定義の契約ではなく、具体的なデータベースアダプターの実装に依存します。そして、古代から大きなOO力が言われてきましたが、これは常に悪いことです。では、上記のソリューションはどのように実装されますか?

    (残りは入力テキストに似ており、必要に応じて調整および簡素化できます)

以上がリスコフ代替原理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
PHP:サーバー側のスクリプト言語の紹介PHP:サーバー側のスクリプト言語の紹介Apr 16, 2025 am 12:18 AM

PHPは、動的なWeb開発およびサーバー側のアプリケーションに使用されるサーバー側のスクリプト言語です。 1.PHPは、編集を必要とせず、迅速な発展に適した解釈言語です。 2。PHPコードはHTMLに組み込まれているため、Webページの開発が簡単になりました。 3。PHPプロセスサーバー側のロジック、HTML出力を生成し、ユーザーの相互作用とデータ処理をサポートします。 4。PHPは、データベースと対話し、プロセスフォームの送信、サーバー側のタスクを実行できます。

PHPとWeb:その長期的な影響を調査しますPHPとWeb:その長期的な影響を調査しますApr 16, 2025 am 12:17 AM

PHPは過去数十年にわたってネットワークを形成しており、Web開発において重要な役割を果たし続けます。 1)PHPは1994年に発信され、MySQLとのシームレスな統合により、開発者にとって最初の選択肢となっています。 2)コア関数には、動的なコンテンツの生成とデータベースとの統合が含まれ、ウェブサイトをリアルタイムで更新し、パーソナライズされた方法で表示できるようにします。 3)PHPの幅広いアプリケーションとエコシステムは、長期的な影響を促進していますが、バージョンの更新とセキュリティの課題にも直面しています。 4)PHP7のリリースなど、近年のパフォーマンスの改善により、現代の言語と競合できるようになりました。 5)将来的には、PHPはコンテナ化やマイクロサービスなどの新しい課題に対処する必要がありますが、その柔軟性とアクティブなコミュニティにより適応性があります。

なぜPHPを使用するのですか?利点と利点が説明されましたなぜPHPを使用するのですか?利点と利点が説明されましたApr 16, 2025 am 12:16 AM

PHPの中心的な利点には、学習の容易さ、強力なWeb開発サポート、豊富なライブラリとフレームワーク、高性能とスケーラビリティ、クロスプラットフォームの互換性、費用対効果が含まれます。 1)初心者に適した学習と使用が簡単。 2)Webサーバーとの適切な統合および複数のデータベースをサポートします。 3)Laravelなどの強力なフレームワークを持っています。 4)最適化を通じて高性能を達成できます。 5)複数のオペレーティングシステムをサポートします。 6)開発コストを削減するためのオープンソース。

神話を暴く:PHPは本当に死んだ言語ですか?神話を暴く:PHPは本当に死んだ言語ですか?Apr 16, 2025 am 12:15 AM

PHPは死んでいません。 1)PHPコミュニティは、パフォーマンスとセキュリティの問題を積極的に解決し、PHP7.xはパフォーマンスを向上させます。 2)PHPは最新のWeb開発に適しており、大規模なWebサイトで広く使用されています。 3)PHPは学習しやすく、サーバーはうまく機能しますが、タイプシステムは静的言語ほど厳格ではありません。 4)PHPは、コンテンツ管理とeコマースの分野で依然として重要であり、エコシステムは進化し続けています。 5)OpcacheとAPCを介してパフォーマンスを最適化し、OOPと設計パターンを使用してコードの品質を向上させます。

PHP対Pythonの議論:どちらが良いですか?PHP対Pythonの議論:どちらが良いですか?Apr 16, 2025 am 12:03 AM

PHPとPythonには独自の利点と短所があり、選択はプロジェクトの要件に依存します。 1)PHPは、Web開発に適しており、学習しやすく、豊富なコミュニティリソースですが、構文は十分に近代的ではなく、パフォーマンスとセキュリティに注意を払う必要があります。 2)Pythonは、簡潔な構文と学習が簡単なデータサイエンスと機械学習に適していますが、実行速度とメモリ管理にはボトルネックがあります。

PHPの目的:動的なWebサイトの構築PHPの目的:動的なWebサイトの構築Apr 15, 2025 am 12:18 AM

PHPは動的なWebサイトを構築するために使用され、そのコア関数には次のものが含まれます。1。データベースに接続することにより、動的コンテンツを生成し、リアルタイムでWebページを生成します。 2。ユーザーのインタラクションを処理し、提出をフォームし、入力を確認し、操作に応答します。 3.セッションとユーザー認証を管理して、パーソナライズされたエクスペリエンスを提供します。 4.パフォーマンスを最適化し、ベストプラクティスに従って、ウェブサイトの効率とセキュリティを改善します。

PHP:データベースとサーバー側のロジックの処理PHP:データベースとサーバー側のロジックの処理Apr 15, 2025 am 12:15 AM

PHPはMySQLIおよびPDO拡張機能を使用して、データベース操作とサーバー側のロジック処理で対話し、セッション管理などの関数を介してサーバー側のロジックを処理します。 1)MySQLIまたはPDOを使用してデータベースに接続し、SQLクエリを実行します。 2)セッション管理およびその他の機能を通じて、HTTPリクエストとユーザーステータスを処理します。 3)トランザクションを使用して、データベース操作の原子性を確保します。 4)SQLインジェクションを防ぎ、例外処理とデバッグの閉鎖接続を使用します。 5)インデックスとキャッシュを通じてパフォーマンスを最適化し、読みやすいコードを書き、エラー処理を実行します。

PHPでのSQL注入をどのように防止しますか? (準備された声明、PDO)PHPでのSQL注入をどのように防止しますか? (準備された声明、PDO)Apr 15, 2025 am 12:15 AM

PHPで前処理ステートメントとPDOを使用すると、SQL注入攻撃を効果的に防ぐことができます。 1)PDOを使用してデータベースに接続し、エラーモードを設定します。 2)準備方法を使用して前処理ステートメントを作成し、プレースホルダーを使用してデータを渡し、メソッドを実行します。 3)結果のクエリを処理し、コードのセキュリティとパフォーマンスを確保します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。