ホームページ > バックエンド開発 > PHPチュートリアル > PHPマスター|デメテルの法則の紹介

PHPマスター|デメテルの法則の紹介

Christopher Nolan
リリース: 2025-02-25 23:26:10
オリジナル
136 人が閲覧しました

PHP Master | Introduction to the Law of Demeter

コアポイント

    最小の知識の原則としても知られているディミットの法則は、他のオブジェクトに対するオブジェクトの理解を最小限に抑えることを支持し、モジュール性と保守性を高めるために直接隣人と対話することのみを支持します。
  • Dimitt Lawを順守することで、ゆるく結合したソフトウェアモジュールの設計を大幅に強化し、コードの保守、テスト、変更を容易にすることができます。
  • ディミッター法の一般的な違反は、オブジェクトまたはメソッドが他のオブジェクトの構造と要素についてあまりにも多くを知っている場合に発生し、その結果、管理と進化が困難なコードが厳しく結合されます。
  • PHPの実用的な例は、他のオブジェクトの内部詳細を公開するサービスロケーターを使用するなど、一般的なプラクティスに違反を巧みに組み込む方法を示しています。
  • コードをリファクタリングして、ディミティアの法律に準拠するには、アーキテクチャを複雑にし、依存関係を増加させる不必要な中間体を避けるために、必要なコンポーネントのみと直接相互作用する必要があります。
  • ディミッター法は、依存関係を減らし、高い結束力を促進することによりコードの品質を向上させますが、特定のコンテキストと複雑さとパフォーマンスのトレードオフを考慮して、実用的に適用する必要があります。
  • ソフトウェアプログラミングは、アートのバランスの取れた組み合わせ(即興のためのe曲表現)と、特定の問題を解決し、まともな方法で解決するための多くの実績のあるヒューリスティックです。芸術的な側面が磨き上げて洗練するのが最も困難であることに反対する人はほとんどいません。一方、ヒューリスティックの背後にある力は、優れた設計に基づいてソフトウェアを開発できるために不可欠です。ソフトウェアシステムが特定の方法に固執する方法と理由を説明する非常に多くのヒューリスティックがあるため、PHPの世界でより広く実装されていないのは非常に残念です。たとえば、ディミティアの法律は、言語分野で最も過小評価されている法律の1つである可能性があります。実際、「あなたの親しい友人とのみ話す」というルールのモットーは、PHPのかなり未熟な状態にあるようであり、それがいくつかのオブジェクト指向のコードベースの全体的な品質の低下をもたらしました。いくつかの一般的なフレームワークは、法律の教訓をさらに遵守するために、積極的にそれを推し進めています。そのような破壊を軽減する最良の方法は、単に実用的な態度をとり、実際に法律に基づいているものを理解することであり、オブジェクト指向のコードを書くときに意識的に適用されることであるため、それは単純に実用的な態度をとることであるため、それは単にオブジェクト指向のコードを書くときに、お互いを非難することは意味がありません。 。正義の原因に加わり、実際の観点から法律をより深く研究するために、次の数行で、法律の原則を観察するのと同じくらい簡単なことがゆるく結合されたソフトウェアモジュールで設計されている理由をいくつか実用的な例で実証します時間は本当に効率を改善できます。

あまりにも多くのことを知っておくのは良いことではありません

はしばしば最小の知識の原則と呼ばれ、ディミテス法によって提唱されている規則は理解しやすいです。簡単に言えば、特定のメソッドを実装する適切に設計されたクラスがあるとしたら、この方法は次のオブジェクトに属する他のメソッドを呼び出すことに限定する必要があります。

  1. メソッドの元のクラスのインスタンス。
  2. ターゲットメソッドのパラメーターオブジェクト。
  3. ターゲットメソッドによって作成されたオブジェクト。
  4. メソッドの元のクラスの依存性オブジェクト。
  5. 元のクラスがターゲットメソッドにアクセスできるグローバルオブジェクト(ああ!)
リストは正式なものとはほど遠いものですが(より正式なリストについては、ウィキペディアをチェックしてください)、これらの重要なポイントは理解しやすいです。従来のデザインでは、別のオブジェクト(3番目のオブジェクトへのアクセス方法を暗黙的に知ることを含む)についてあまりにも多くを知ることは間違っていると考えられています。予想どおりに機能する必要があります。これは、明らかな理由で深刻な設計上の欠陥です。発信者は、いくつかのゲッターからアクセスされたとしても、中間体の内部構造についてかなり広範かつ詳細な理解を持っています。さらに、中間オブジェクトを使用して発信者が必要とするオブジェクトを取得すること自体が問題を示しています。結局のところ、依存関係を直接注入することで同じ結果を達成できる場合、なぜこのような複雑なパスを使用して依存関係を取得するか、その方法のいずれかを呼び出すのですか?このプロセスにはまったく意味がありません。

多型エンコーダーを内部的に使用して、データを取得して指定されたターゲットファイルに保存するファイルストレージモジュールを構築する必要があると仮定します。モジュールを注射可能なサービスロケーターに意図的にずさんに接続すると、その実装は次のようになります。

Filestorageクラスのコンストラクターとそのwrite()およびread()メソッドに焦点を当てた、無関係な実装の詳細を省略します。このクラスは、定義されていないサービスロケーターのインスタンスを注入し、後でターゲットファイルにデータを取得および保存するために依存関係(前述のエンコーダー)を取得するために使用されます。これは通常、クラスが最初にロケーターを横断し、次にエンコーダーに到達することを考慮して、ディミッター法の違反です。発信者FileStorageは、エンコーダーへのアクセス方法など、ロケーターの内部構造についてあまりにも知っています。これは間違いなく賞賛したい機能ではありません。これは、本質的にサービスロケーターの性質(そのため、一部の人々はそれをアンチパターンと考えている理由)または他のタイプの静的または動的レジストリに根ざしたアーティファクトです。この問題をより包括的に理解するには、ロケーターの実装を確認しましょう。
<?php namespace LibraryFile;
use LibraryDependencyInjectionServiceLocatorInterface;

class FileStorage
{
    const DEFAULT_STORAGE_FILE = "data.dat";
    private $locator;
    private $file;

    public function __construct(ServiceLocatorInterface $locator, $file = self::DEFAULT_STORAGE_FILE)  {
        $this->locator = $locator;
        $this->setFile($file);
    }

    public function setFile($file) {
        if (!is_readable($file) || !is_writable($file)) {
            throw new InvalidArgumentException(
                "The target file is invalid.");
        }
        $this->file = $file;
        return $this;
    }

    public function write($data) {
        try {
            return file_put_contents($this->file, 
                $this->locator->get("encoder")->encode($data),
                LOCK_EX);
        }
        catch (Exception $e) {
            throw new $e(
                "Error writing data to the target file: " . 
                $e->getMessage());
        }
    }

    public function read() {
        try {
            return $this->locator->get("encoder")->decode(
                @file_get_contents($this->file));
        }
        catch(Exception $e) {
            throw new $e(
                "Error reading data from the target file: " .
                $e->getMessage());
        }
    }
}
ログイン後にコピー
(ロケーターとエンコーダーのコードは、以前の出力と一致しているため、ここでは省略されています。複製を避けるために、ここで繰り返されません。)

エンコーダーを使用して、すべてのサンプルクラスを一緒に始めましょう。

(以前の出力と一致しているため、使用法のサンプルコードはここで省略されています。複製を避けるために、ここで繰り返しません。)

この場合、この法律の違反はかなり秘密の問題であり、ロケーターの突然変異体の使用を除き、表面から追跡することは困難です。そして使用します。いずれにせよ、私たちが違反が外の世界の外に隠されていることを知っているという事実は、ロケーター構造に関するあまりにも多くの情報を明らかにするだけでなく、FileStorageクラスをロケーター自体に不必要に結合します。このルールのルールに従ってロケーターを取り除くだけで、ビジネスを行うために必要な実際の協力者とFileStorageを提供しながら、結合を削除できます。途中で不器用で露出した中間体はもうありません!幸いなことに、このナンセンスはすべて、少しの努力で作業コードに簡単に変換できます。 Filestorageクラスの拡張されたDimitriの法律準拠バージョンをここに表示するだけです:

(以前の出力と一致しているため、リファクタリングされたFilestorageコードはここで省略されています。複製を避けるために、ここで繰り返されません。)

これは本当に簡単にリファクタリングできます。これで、クラスはEncoderInterfaceインターフェイスの実装者を直接使用し、不要な中間体の内部構造を通過することを避けます。この例は間違いなく些細なことですが、妥当性のポイントを示し、ディミトリの法律の教訓に従うことがクラスの設計を改善するためにできる最善のことの1つである理由を示しています。ただし、この規則の特別なケースは、ロバートマーティンの著書「The Way of Code:Agile Software Development Manual」で深く調査されており、特別な分析に値します。慎重に考えてみてください:Filestorageがデータ転送オブジェクト(DTO)を介してコラボレーターを取得すると定義された場合はどうなりますか?

(DTOを使用したコード例は、以前の出力と一致しているため、ここでは省略されています。複製を避けるために、ここで繰り返されません。)

これは間違いなくファイルストレージクラスを実装するための興味深い方法です。これは、注入可能なDTOを使用してエンコーダーを内部的に転送および使用するためです。答えられるべき問題は、この方法が本当に法律に違反しているかどうかです。純粋主義者の観点からは、DTOは間違いなくその構造全体を発信者にさらす中間体であるため、違反します。ただし、DTOは、以前のサービスロケーターとは異なり、通常のデータ構造にすぎません。まったく動作しません。そして、データ構造の目的は...はい、データを開示することです。これは、中間体が動作を実装していない限り(これは通常のクラスの動作とは正反対であり、動作を公開するためにデータを隠す)、ディミッター法はそのままのままであることを意味します。次のコードスニペットは、問題のあるDTOを使用してFileStorageの使用方法を示しています:

(DTOを使用したコード例は、以前の出力と一致しているため、ここでは省略されています。複製を避けるために、ここで繰り返されません。)

このアプローチは、エンコーダーをファイルストレージクラスに直接渡すよりもはるかに面倒ですが、この例は、法律の露骨な違反と一目で見えるかもしれないトリッキーな実装が、通常は非常に無害であることを示しています。追加の動作なしでデータ構造を使用するだけです。

結論

さまざまな複雑で、時には難解なヒューリスティックがOOPで人気があるため、層コンポーネントの設計に明らかにプラスの影響を与えない別の原則を追加することは意味がないようです。ただし、ディミッター法は、現実の世界ではほとんど適用されない原則ではありません。ゴージャスな名前にもかかわらず、Dimitt Lawは、不必要な中間体を排除することにより、高度に分離されたアプリケーションコンポーネントの実装を促進するという主な目標を持つ強力なパラダイムです。その教訓に従ってください。もちろん、盲目的に独断的にならないでください。コードの品質が改善されることがわかります。確保する。

(FAQの部分は以前の出力と一致しているため、ここでは省略されています。複製を避けるために、ここで繰り返しません。)

以上がPHPマスター|デメテルの法則の紹介の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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