ホームページ >バックエンド開発 >PHPチュートリアル >PHPマスター|デメテルの法則の紹介
コアポイント
はしばしば最小の知識の原則と呼ばれ、ディミテス法によって提唱されている規則は理解しやすいです。簡単に言えば、特定のメソッドを実装する適切に設計されたクラスがあるとしたら、この方法は次のオブジェクトに属する他のメソッドを呼び出すことに限定する必要があります。
多型エンコーダーを内部的に使用して、データを取得して指定されたターゲットファイルに保存するファイルストレージモジュールを構築する必要があると仮定します。モジュールを注射可能なサービスロケーターに意図的にずさんに接続すると、その実装は次のようになります。
Filestorageクラスのコンストラクターとそのwrite()およびread()メソッドに焦点を当てた、無関係な実装の詳細を省略します。このクラスは、定義されていないサービスロケーターのインスタンスを注入し、後でターゲットファイルにデータを取得および保存するために依存関係(前述のエンコーダー)を取得するために使用されます。これは通常、クラスが最初にロケーターを横断し、次にエンコーダーに到達することを考慮して、ディミッター法の違反です。発信者FileStorageは、エンコーダーへのアクセス方法など、ロケーターの内部構造についてあまりにも知っています。これは間違いなく賞賛したい機能ではありません。これは、本質的にサービスロケーターの性質(そのため、一部の人々はそれをアンチパターンと考えている理由)または他のタイプの静的または動的レジストリに根ざしたアーティファクトです。この問題をより包括的に理解するには、ロケーターの実装を確認しましょう。
<code class="language-php"><?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()); } } }</code>(ロケーターとエンコーダーのコードは、以前の出力と一致しているため、ここでは省略されています。複製を避けるために、ここで繰り返されません。)
エンコーダーを使用して、すべてのサンプルクラスを一緒に始めましょう。
(以前の出力と一致しているため、使用法のサンプルコードはここで省略されています。複製を避けるために、ここで繰り返しません。)
この場合、この法律の違反はかなり秘密の問題であり、ロケーターの突然変異体の使用を除き、表面から追跡することは困難です。そして使用します。いずれにせよ、私たちが違反が外の世界の外に隠されていることを知っているという事実は、ロケーター構造に関するあまりにも多くの情報を明らかにするだけでなく、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 サイトの他の関連記事を参照してください。