3

私は持っています、DataMapperFactoryそして私はそれを正しくやっていると思います、そしてそれを持っていることは理にかなっています、しかし私も持っていDomainObjectFactoryます、しかしそれはただ無意味に思えます。これだよ:

namespace libs\factories;
use models as Models;

class DomainObjectFactory {

    public function build($name) {

        $className = 'Models\\' . $name;

        return new className();

    }

}

これについて私が見ることができる唯一の利点はnew、コード全体にオペレーターが存在しないようにしていることです。

DomainObjectFactoryこの権利以上のものが必要ですか?

どんな助けでも大いに感謝します。

4

3 に答える 3

6

工場を使用する主な理由があります:

1.オブジェクトの作成を抽象化します

これは、単体テストに関して、アーキテクチャで最も有用な構造の1つです。インスタンスの作成をファクトリに任せることで、テスト時にモックを簡単に導入できます。

また、追加の利点として、使用するクラスの名前と密接に結びついているわけではありません。

2.インスタンス化を簡素化します

ここでは、考慮しなければならない2つの側面があります。まず、ある条件に基づいてさまざまなオブジェクトをインスタンス化する機能は、 helmbertの回答 (彼の場合は+1)ですでに十分に説明されています。

もう1つのケースは、より複雑なドメインオブジェクトをインスタンス化する場合です。このようなもの:

$employees = new EmployeeCollection;
$address = new Location;
$class = $type . `Company`;
$company = new $class( $employee, $address );

のインスタンスを作成する前に、やるべきことがたくさんありますHoldingCompany。しかし、このプロセス全体は工場で行うことができます。特に、ドメインオブジェクトファクトリが正しく実装されたDICをうまく利用している場合(これは非常にまれですが)。

3.アプリケーションでリリースされる前にオブジェクトを準備します

コンストラクターで計算を実行しないでください。そのコードをテストすることは不可能になります。コンストラクターには、単純な変数の割り当てのみを含める必要があります。

ただし、これにより問題が発生します。インスタンス化されたオブジェクトを他のコード構造で処理できるようにする前に、いくつかの論理演算を実行する必要がある場合があります。初心者として、私たちは通常コンストラクターでそれを行います。しかし、今どこにそれを置くのですか?

これは、工場が救助に来るところです。

public function create( $name )
{
     $instance = new $name;
     if ( is_callable($instance, false, 'prepare') )
     {
         $instance->prepare();
     }
     return $instance;
}

これで、を使用する$factory->create('foobar')と、オブジェクトが完全に準備されて使用できるようになります。


于 2013-02-19T19:46:09.643 に答える
5

一般に、ファクトリを使用して特定の実装から抽象化できます。演算子を使用すると、new <classname>毎回特定のクラスをインスタンス化します。後でこのクラスを別の実装と交換する場合は、すべてのnewステートメントを手動で変更する必要があります。

ファクトリパターンを使用すると、特定のクラスから抽象化できます。有効な最小限のユースケースは次のようになります。

interface UserInterface {
    public function getName();
}

class UserImplementationA implements UserInterface {
    private $name;
    public function getName() { return $this->name; }
}

class UserImplementationB implements UserInterface {
    public function getName() { return "Fritz"; }
}

class UserFactory {
    public function createUser() {
        if (/* some condition */) return new UserImplementationA();
        else                      return new UserImplementationB();
    }
}

$f = new UserFactory();
$u = $f->createUser();   // At this point, you don't really have to care 
                         // whether $u is an UserImplementationA or
                         // UserImplementationB, you can just treat it as
                         // an instance of UserInterface.

これが非常に役立つ場合の(多くの)ユースケースの1つは、単体テストで作業する場合です。テスト駆動開発では、クラスの依存関係をモックオブジェクト(特定のインターフェイスを実装するが実際には何もしないオブジェクト)に置き換えることがよくあります。ファクトリパターンを使用すると、特定のクラスをモッククラスに透過的に置き換えることが非常に簡単になります。

于 2013-02-19T19:22:55.857 に答える
1
public function build($name) {

        $className = 'Models\\' . $name;

        return new $className();
}

それはあなたのために働くでしょう。

オブジェクトにデフォルトのプロパティを設定する場合は、オブジェクトファクトリを定義することをお勧めします。また、クラスが存在する名前空間やディレクトリについて心配する必要はありません。

例:

public function createButton($name){
    require("home/lib/display/Button.php") ;

    $button = new Button($name, "some default param") ;
    $button->visible = true ;
    return $button ;
}

言葉を遠ざけるだけでなく、そのようなファクトリを介してデフォルトのオブジェクトをすばやく作成するだけnewです。

于 2013-02-19T19:11:39.657 に答える