3

私のタイトルが正しいかどうかわからないので、正しい用語を使用しているかどうかさえわかりません.

オブジェクトであるプロパティを持つクラスがあります。このプロパティを設定するときは、オブジェクトを作成する必要があります。私の質問は、密結合なしでこれを行うにはどうすればよいですか?

例:

class A
{
    protected $_depending;

    protected $_somePropertyObject;

    public function __construct(\Lib\Dependency $depending)
    {
        $this->_setDepending($depending);
    }

    protected function _setDepending(\Lib\Dependency $depending)
    {
        $this->_depending = $depending;
    }

    public function setSomeProperty($someProperty)
    {
        // I want to prevent this
        $this->_somePropertyObject = new \Lib\some\Object($someProperty);
    }
}

必要なオブジェクトをコンストラクトに渡すこともできますが、さらに必要な場合はどうなりますか?

工場のパターンを正しく理解すると、いつ何が変わるでしょうか? オブジェクトをどこかに作成する必要がありますか? オブジェクト自体ではなく、工場です。また密結合?私には無限に思えます。ただし、クラスをリファクタリングする場合、クラスがどこでどのように作成されるかは分離されます。

\Lib\some\Object のみを受け入れるように setSomeProperty 関数を設定した場合でも、最初にそれを渡す親オブジェクトによって作成される必要があります。それが作成された場所の配置をシフトするだけのようですか?

うまくいけば、私が尋ねようとしていることは十分に明確です。

前もって感謝します!

編集私が求めているのは、いつ、どこで、なぜ作成されるかのシーケンスです。

4

2 に答える 2

5

依存性注入パターンでのファクトリの目的は、別のインスタンスのインスタンスを生成することです。他のインスタンスはインスタンスの生成方法を知る必要はありません。

本質的に、「ファクトリ」は単にオブジェクトを返すものであり、呼び出されたときにインスタンスを返すものです。

これは、より有能な言語で見やすくなります。たとえば、Python ではクラスは呼び出し可能 (new演算子はありません) であり、クラスを呼び出すとクラスのインスタンスが生成されます。そのため、クラスが引数を必要としない場合、クラスは独自のファクトリになることができます。同様に、インスタンスを返す引数のない関数は、ファクトリと見なすことができます。これにより、依存性注入が非常に明確になり、ボイラープレートがなくなります。

より厳格な言語 (Java/C++/C# の静的型付けの伝統、またはクラスや関数が PHP のように完全にファーストクラスではない) では、 「デザイン パターン」が欠落しているため、「パターン」の背後にある依存性注入を覆い隠す必要があります。言語機能。PHP 5.3+ では、クロージャをファクトリとして使用するか、Java/C# の方法でFactoryInterfaceファクトリごとに および新しいクラスを定義できます。

たとえば、あなたのクラスでは、これを行うことができます:

class Aprime extends A
{
    public function setSomeProperty($somePropertyFactory)
    {
        $this->_somePropertyObject = $somePropertyFactory();
    }
}

このクラスでsetSomePropertyは、次のように生成できる、引数なしの呼び出し可能な「factory」が必要です。

$other_dep_factory = function(){ return new SomeOtherClass(); };

またはこのように:

class ClassFactory {
    function __construct($classname, $args=array()) {
        $this->class = new ReflectionClass($classname);
        $this->args = $args;
    }

    function __invoke() {
        return $this->class->newInstanceArgs($this->args);
    }
}

$other_dep_factory = new ClassFactory('SomeOtherClass');

PHP 5.3 より前では、Java のように行う必要があります。

interface IObjectFactory {
    function getObject();
}

// this B-and-D interface is optional
// it has no body because PHP doesn't support
// type-hinting return values
interface ISomeOtherClassFactory {}


class SomeOtherClassFactory implements ISomeOtherClassFactory {
    function getObject() {
        return new SomeOtherClass();
    }
}

class Aprime extends A
{
    public function setSomeProperty(ISomeOtherClassFactory $somePropertyFactory)
    {
        $this->_somePropertyObject = $somePropertyFactory->getObject();
    }
}


$other_dep_factory = new SomeOtherClassFactory();
$myAprimeObject->setSomeProperty($other_dep_factory);

では、いつファクトリを使用しますか? オブジェクトが別のオブジェクトを作成する必要があるとき。オブジェクトが別のオブジェクトを使用する必要がある場合は、インスタンスを渡すだけです。

于 2013-03-27T17:20:55.810 に答える
0

$_somePropertyObject に格納されるオブジェクトを作成するために「情報」を収集する必要がある場合は、Factory パターンを使用するのが好きです。たとえば、いくつかのプロパティに値を割り当ててインスタンス化するか、インスタンス化した直後にいくつかのメソッドを実行する必要があるとします。

また、後で継承ツリーを変更する必要があるかどうかを検討する必要があります。今 $_somePropertyObject を \Lib\some\Object に割り当てている場合、後で簡単に \Lib\some\FancyObject に交換したいと思うかもしれません。依存性注入を使用すると、サブタイプを簡単に交換できます。

ここに入門書があります: http://net.tutsplus.com/tutorials/php/the-whens-and-whys-for-php-design-patterns/

また、あまりにも: https://stackoverflow.com/a/2083455/1121827

于 2013-03-27T16:52:39.647 に答える