2011-12-28 75 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)上设置了一个param

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

第二种方式具有更少的代码,并且是更好的。为什么要创建多种方式来设置名字? – 2011-12-28 22:46:30

+0

根据@ mmmshuddup的回答,我不认为这实际上是工厂模式。 – McKay 2011-12-28 22:59:00

+0

http://en.wikipedia。org/wiki/Factory_method_pattern – McKay 2011-12-28 22:59:23

回答

3

我始终认为,应用的工厂模式的方法是,当有多种类型的,说返回不同的类实现基地工厂,用户。例如,管理超级管理员。你可以有像这样一个工厂方法:

// 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; 
    } 
} 

两个 - 或任何为此事 - 的用户类将implement某种接口定义这些getter和你使用像setFirstName()setAge()例如setter方法。

你也可以定义一个$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的一个示例:

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

然后当你实例化它,这是因为像这样简单:

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

+1是的,这是工厂模式的正确模型 – McKay 2011-12-28 22:58:18

+0

“定义创建对象的接口,但让子类决定实例化哪个类。Factory方法让类将实例化延迟到子类。 http://en.wikipedia.org/wiki/Factory_method_pattern#cite_ref-0 – McKay 2011-12-28 23:01:28

+0

带有$ options数组的东西是没有我可以使用的接口。数组可以包含所有内容,并且不包含任何类型的值。要知道我可以给这个创建方法什么,我应该挖掘代码并尝试理解我可以定义的内容。 相比之下,班级定义了一个很好的签名,我可以在那里发言并确切知道我可以用它做什么。如果你工作的用户类,你知道你可以分配firstName .. – 2011-12-28 23:10:20

1

您是第只有可以决定这个的人。您应该考虑以下选项:

  1. 您的用户实例在构造函数中总是需要相同类型的输入吗?那么将它们传递给工厂方法是一个不错的选择。
  2. 是否返回的实例取决于你需要实例化类型的用户?如果是这样,您将不得不将正确的参数传递给工厂,以便它可以为您做出决定。在不久的将来看看你需要什么是很重要的。不要通过太多或太少。
  3. 可以创建一个DTO(数据传输对象)类来定义用户的所有属性。这样,您可以将大量信息传递给工厂方法,并且可能对未来有更多的防范措施(如角色,权限等)。
  4. 有些人可能会说只是将所有的信息传递给工厂方法,所以所有的逻辑都可以通过工厂方法来执行,即使现在不需要。