Which is the best way to implement factory method.
1) A factory method that contain all members of the model to define
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) A factory method that simply create the model and return it. After we can fill the model by using the model setters.
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) A Factory that return a different class implementation base on a 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();
}
The way I’ve always seen the factory pattern applied is when there are multiple types of, say, users. For example, admin and superadmin. You could have a factory method like so:
Both – or ANY for that matter – of the User classes would
implementsome sort of interface that defines those getters and setters you were using likesetFirstName()andsetAge()for example.You could also define an
$optionsarray or something to pass along to each of their constructors to instantiate all of those fields right away for you.Then, here is an example of one of the contructors:
Then when you instantiate it, it’s as simple as something like this: