web-dev-qa-db-ja.com

名前付きコンストラクターが人気を博している理由は、アンチパターンであってはなりませんか?

次の記事によると 名前付きコンストラクタ 著者は、static factory patternを使用してオブジェクトを構築する方が、newキーワードを使用してインスタンス化するよりも優れていると示唆しています。当初、アイデアは魅力的です(記事の詳細によると)はい、メソッド名はより明白であり、クラスの構築はその構築者に依存していませんが、クラスは構築上のさまざまな問題に応じてさまざまな動作をしているという感覚を与えますレベル。

<?php
$customer = new Customer($name); 
// We can't "new a customer" or "instantiate a customer" in real life.
// Better:
$customer = Customer::fromRegistration($name);
$customer = Customer::fromImport($name);

しかし、このイディオムに従ってここで見られる問題は、methodsのようなクラスfunctionsを使用しています!上記の例によれば、カップリングの問題が発生するため、これをstatic factoriesを注入可能なファクトリでラップして、アプリケーションの他の部分から切り離す必要がありますか?

これを理解するために私を明確にしていただけませんか。私はこのイディオムをPHPコミュニティで、そしていくつかのJavaの例でさえ見始めました。

1
FZE

PHPの名前付きコンストラクタ

PHPの単一のコンストラクターに制限されないでください。静的ファクトリメソッドを使用します。

この記事はカップリングに関するものではありません。 new Customer(/* some args */)Customer::fromFoo(/* some args */)を使用しても、カップリングに違いはありません。どこでputこれらの式は、それらがどの程度結合されているかを決定します。要約すると、「ファクトリパターン」は「オブジェクトを返す式」です。

違いは、代わりに、単一のコンストラクターを持つクラスに対するPHPの制限を回避することです。クラスを構築する複数の方法が必要な場合は、2つの選択肢があります。

  • 引数から、単一のコンストラクターでそれらを区別します
  • それらを、互いに異なる引数を取る複数の静的ファクトリで区別します。
7
Caleth

PHPでは、クラスごとに複数のコンストラクタはありませんが、同じ名前が付けられているため、とにかく役に立ちません:__construct、ユビキタス言語に由来しない用語。

しかし、なぜとにかくコンストラクターを使用するのですか?これを使用して、オブジェクトを有効な初期状態に正しく開始します。これを行うには、プロパティをプライベートにします。これは、オブジェクトのカプセル化の保護にも役立ちます。これは、それらがクラスのコンテキストからのみ変更されるである可能性があることを意味します。問題は、多くのオブジェクトに複数の有効な初期状態が存在する可能性があることです。したがって、初期の有効な状態のみを許可し、カプセル化を保護するために、クラス静的メソッドをオブジェクトコンストラクターとして使用できます(ユースケースごとに1つ)。

C++には、プライベートプロパティにアクセスできる フレンドクラス があるため、それらは、各ユースケースのファクトリとしてフレンドクラスを持つことができますがweはしないので、静的メソッドを使用する必要があります。

ところで、コンテキストはクラスであるため、静的メソッドを使用してもカプセル化は中断されません。 PHPを使用すると、静的クラスのメソッドからprivateのプロパティとメソッドにアクセスできます。

0