doutang1884 2015-05-25 12:06
浏览 64

删除“工厂”< - >“具体实现”依赖项

I have a "provider factory" which creates an implementation of a concrete provider. To create correct implementation it needs, among other parameters, typeId. The problem is that in order to pass the correct typeId to the factory, I need to validate and, if necessary, change it. And in order to do that, among other parameters, I need an instance of a particular provider. Which is where the problem is - the provider should be singleton (I really don't want to make it a Singleton with a capital S), because it queries a database and caches the result in the internal property.

So my question is - is there a more suitable pattern to use or another way to achieve something similar?

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);
  • 写回答

1条回答 默认 最新

  • doudi5524 2015-05-26 09:04
    关注

    I suggest you to implement ChainOfResponsibility pattern in ProviderFactory, so that you don't need to modify ProviderFactory each time new Provider is added or logics changed. You just need to add RegisterProvider(IProvider provider) method to add providers in chain and then just cycle through this chain of providers calling bool:DoesProviderSuit(int typeId, out IProvider) of each IProvider.

    Hope you catch an idea, good luck!

    评论

报告相同问题?

悬赏问题

  • ¥15 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?
  • ¥15 matlab(相关搜索:紧聚焦)
  • ¥15 基于51单片机的厨房煤气泄露检测报警系统设计