创作模式:“Bastard Factory”,一个抽象工厂衍生品

时间:2010-07-29 10:25:56

标签: php design-patterns factory creation

我目前正在试图找出在我当前的PHP 5.2项目中创建对象的最佳方法。我基本上有一个注册表,它通过键返回对象。如果注册表没有具有指定键的对象,它将尝试通过调用通过构造提供给注册表的工厂方法来创建一个对象。请查看以下代码以进行校准:

interface IFactory
{
    public function createProduct( $key );
}

class Registry
{
    private $m_elements = array( );
    private $m_factory;
    public function __construct( IFactory $factory )
    {
       $this->m_factory = $factory;
    }
    public function getElement( $key )
    {
      if ( !array_key_exists( $key, $this->m_elements ) )
      {
          $this->m_elements[$key] = $this->m_factory->createProduct( $key );
      }
      return $this->m_elements[$key];
    }
}

因为我想在不同的注册表中存储不同类别的对象,所以我将一个Registry对象包装成每个类别的单例,如下所示:

class SpecialRegistry
{
   private static $instance = null;

   public static function getInstance( )
   {
       if( self::$instance === null )
       {
           self::$instance = new Registry( new SpecialFactory( ) );
       }
       return self::$instance;
   }
}

我的特殊课程相当复杂和庞大,有很多不同的属性和组合对象。因为我不想将我的Special类绑定到任何特定的后端,所以我将为每个不同的后端(例如MySQL数据库或文件流)使用不同的工厂。所以我会将加载和初始化逻辑移到工厂。但是,只有在Special类中的所有字段都是Factory的公共字段时才会有效。但是,他们不应该公开申请的其余部分。

在C ++中,我可以使用朋友来规避这个问题。 此外,关于堆栈溢出,我读了几乎相同的主题,但应用于C#。它说我应该简单地在Special类中设置所有字段public,并让Factory只返回一个接口,该接口公开我想要公开给应用程序的方法和属性。但由于PHP不支持返回类型提示,因此我无法仅返回Special类实现的接口。 我提出的另一种方法是实际上从Special类继承SpecialFactory,从而可以从工厂访问私有和受保护的字段。这就是我所谓的“Bastard Factory”,因为工厂继承了它自己的产品。

我想知道你们中是否有人能想出一个更好的方法来实现我想要的东西。或者我是否完全偏离轨道并且向工厂提供初始化过程是绝对禁止的?我很好奇你的意见!

1 个答案:

答案 0 :(得分:1)

来自Java背景,如何在那里添加构建器?此构建器可以通过工厂可以构建的公共字段来显示其状态。构建器完成后,将其传递给Special类,并让它从构建器加载其状态。

你工厂里的这种东西(伪代码):

public function createProduct() {
  SpecialBuilder builder = new SpecialBuilder();
  // Do whatever you would have done to the Special class to the builder
  // ...
  Special special = new Special(builder);
  return special;
}

通过这种方式,您的特殊对象仍然可以隐藏其内部状态。我看到的唯一真正的缺点是它是一个轻微的对象过载情况。