【发布时间】:2015-08-06 21:56:53
【问题描述】:
我有一个“提供者工厂”,它创建了一个具体提供者的实现。要创建正确的实现,除了其他参数之外,它还需要 typeId。 问题是为了将正确的 typeId 传递给工厂,我需要验证并在必要时进行更改。 为了做到这一点,除其他参数外,我需要一个特定提供者的实例。这就是问题所在 - 提供者应该是单例的(我真的不想让它成为带有大写 S 的单例),因为它查询数据库并将结果缓存在内部属性中。
所以我的问题是 - 是否有更合适的模式或其他方式来实现类似的目标?
class ProviderFactory
{
public function createProvider($typeId)
{
if ($typeId == 2) {
return new Provider2($arg1, $arg5);
} elseif ($typeId == 4) {
return new Provider4();
} else {
return new ProviderDefault($typeId, $arg1, $arg2, $arg3, $arg4);
}
}
}
interface ProviderInterface
{
public function getCost();
}
class ProviderDefault implements ProviderInterface
{
public function __construct($arg1, $arg2, $arg3, $arg4) {}
public function getCost() { /*implementation*/ }
}
class Provider2 implements ProviderInterface
{
public function __construct($arg1, $arg5) {}
public function getCost() { /*implementation*/ }
}
// this call can be implemented with the following condition
// if ($typeId == 2) {
// if ($provider2->getCost() !== null)
// $typeId = 1;
// }
//
$typeId = fixAndValidateTypeId($typeId, new Provider2($arg1, $arg5));
$factory = new ProviderFactory();
$provider = $factory->createProvider($typeId);
【问题讨论】:
-
只需添加一个静态方法即可从您的提供者那里检索您需要的任何内容。对于这样一个微不足道的用例,不需要单例。
-
@r3wt 我真的很想避免使用静态方法,而是在真实对象上调用方法,因为在硬编码类上调用静态方法会使单元测试更加复杂。不过,感谢您的提示。我认为,如果其他一切都失败了,我将不得不使用静态方法
标签: php design-patterns factory circular-dependency