这是实现工厂方法的最佳方法

时间:2011-12-28 22:41:23

标签: php architecture coding-style domain-driven-design

这是实施工厂方法的最佳方式。

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();
}

2 个答案:

答案 0 :(得分:3)

我总是看到应用工厂模式的方式是,当有多个类型的用户时。例如, admin superadmin 。你可以有这样的工厂方法:

// 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和setter,例如setFirstName()setAge()。 / p>

您还可以定义一个$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;
    }
}

然后,这是其中一个结构的示例:

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

然后当你实例化它时,它就像这样简单:

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

答案 1 :(得分:1)

你是唯一可以决定这一点的人。您应该考虑以下选项:

  1. 您的用户实例是否始终在构造函数中需要相同类型的输入?然后将它们传递给工厂方法是一个不错的选择。
  2. 返回的实例是否依赖于您需要实例化的用户类型?如果是这样,您必须将正确的参数传递给工厂,以便它可以为您决定。在不久的将来看你需要什么是很重要的。不要过多或过少。
  3. 您可以创建一个dto(数据传输对象)类来定义用户的所有属性。这样,您可以将大量信息传递给工厂方法,这可能是未来更具弹性的证据(如角色,权限等)。
  4. 有些人可能会说只是将所有信息传递给工厂方法,因此所有逻辑都可以通过工厂方法执行,即使现在不需要。