2011-12-28 3 views
1

ファクトリメソッドを実装する最良の方法はどれですか。ファクトリメソッドを実装する最良の方法はどれですか

1)

class UserFactory { 
    /** 
    * @return UserModel 
    */ 
    function create($firstName, $lastName, $age) { 
     $user = new UserModel(); 
     $user->setFirstName($firstName); 
     $user->setLastName($firstName); 
     $user->setAge($age); 
     return $user; 
    } 
} 

// Usage example 
$user = $userFactory->createUser('Yanik', 'Lupien', 99); 
$userRepo->persist($user); 

2を定義するために、モデルのすべてのメンバーを含むファクトリメソッド)は、単にモデルを作成し、それを返すファクトリメソッド。モデルセッターを使用してモデルを埋めることができたら

class UserFactory { 
    /** 
    * @return UserModel 
    */ 
    function create() { 
     $user = new UserModel(); 
     return $user; 
    } 
} 

// Usage example 
$user = $userFactory->create(); 
$user->setFirstName('Yanik'); 
$user->setLastName('Lupien'); 
$user->setAge(99); 

$userRepo->persist($user); 

3)複数の種類のがあるとき、私は常に適用される工場のパターンを見てきた方法です

class MyUserFactory { 

    const ADMIN = 'admin'; 
    const SUPER_ADMIN = 'superadmin'; 

    public function create($type = self::ADMIN) 
    { 
    switch ($type) { 
    case self::SUPER_ADMIN: 
     return new UserSuperAdmin($options); 
     break; 

    case self::ADMIN: 
    default: 
     return new UserAdmin($options); 
     break; 
    } 
} 

// Usage 
$user = $myUserFactory->create(MyUserFactory::SUPER_ADMIN); 

if ($user instanceof UserSuperAdmin) { 
    $user->setSuperAdminProperties(); 
} 

if ($user instanceof UserAdmin) { 
    $user->setAdminProperties(); 
} 
+0

第2の方法はコードが少なく、より優れています。ファーストネームを設定する複数の方法を作成する理由 –

+0

@ mmmshuddupの答えによると、私はこれが実際に工場のパターンだとは思わない。 – McKay

+0

http://en.wikipedia。org/wiki/Factory_method_pattern – McKay

答えて

3

は、言うのparamに異なるクラスの実装のベースを返すファクトリー、ユーザー。たとえば、adminおよびスーパー管理者です。

// within a class named "User" for example 
const ADMIN = 'admin'; 
const SUPER_ADMIN = 'superadmin'; 

// ... 

public static function factory($type = 'admin') 
{ 
    switch ($type) { 
     case self::SUPER_ADMIN: 
      return new UserSuperAdmin(); 
      break; 

     case self::ADMIN: 
     default: 
      return new UserAdmin(); 
      break; 
    } 
} 

両方を - またはそのことについては、 - ユーザクラスのは、あなたが例えばsetFirstName()setAge()のように使用していたものをgetterとsetterを定義するインタフェースのいくつかの並べ替えをimplementう:あなたはそうのようなファクトリメソッドを持つことができます。

$optionsの配列や何かをコンストラクタに渡して定義して、すぐにそれらのフィールドをすべてインスタンス化することもできます。

public static function factory($type = 'admin', $options = array()) 
{ 
    switch ($type) { 
     case self::SUPER_ADMIN: 
      return new UserSuperAdmin($options); 
      break; 

     case self::ADMIN: 
     default: 
      return new UserAdmin($options); 
      break; 
    } 
} 

次に、ここでcontructorsの1の例である:あなたがそれをインスタンス化するとき

class UserAdmin implements IUserInterface // for example 
{ 
    public function __construct($options) 
    { 
     // do something with the options array 
    } 
} 

はその後、それはこのようなものと同じくらい簡単です:

$user = User::factory('admin'); 
+1

+1はい、これはファクトリパターンの正しいモデルです – McKay

+0

"オブジェクトを作成するインタフェースを定義しますが、サブクラスがインスタンス化するクラスを決定させるようにします。 http://en.wikipedia.org/wiki/Factory_method_pattern#cite_ref-0 – McKay

+0

$ options配列を使用したことは、私が扱えるインターフェースがないことです。配列には、すべてのものを含めることができ、型付きの値を持つものは何もありません。この作成方法に何を与えることができるかを知るためには、コードを掘り下げて定義できるものを理解しなければなりません。 対照的に、クラスは私が話すことができ、私がそれを使ってできることを正確に知ることができる素敵な署名を定義します。 Userクラスを操作する場合は、firstNameを割り当てることができます。 –

1

あなたがいますこれを決めることができる人だけ。次のオプションを考慮する必要があります。

  1. ユーザーインスタンスは常にコンストラクタで同じ種類の入力を必要としますか?次に、ファクトリメソッドに渡すのは良い選択です。
  2. 返されるインスタンスは、インスタンス化する必要があるユーザーの種類によって異なりますか?もしそうなら、正しいパラメータを工場に渡さなければならないので、それを決定することができます。近い将来、必要なものを探すことが重要です。あまりにも過度に過ぎないでください。
  3. dto(データ転送オブジェクト)クラスを作成して、ユーザーのすべてのプロパティを定義できます。このようにして、ファクトリメソッドに多くの情報を渡すことができ、将来(ロール、パーミッションなど)のためにもっと弾丸になる可能性があります。
  4. あなたが持っているすべての情報をファクトリメソッドに渡すと言う人もいるでしょう。なぜなら、今のところ必要でないとしても、すべてのロジックをファクトリメソッドで実行できるからです。
関連する問題