0

我目前正在尝试找出在我当前的 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];
    }
}

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

class SpecialRegistry
{
   private static $instance = null;

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

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

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

我想知道你们中是否有人能想出一个更好的方法来实现我想要的。还是我完全偏离了轨道,将初始化过程交给工厂是绝对不行的?我很好奇你的意见!

4

1 回答 1

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

这样,您的 Special 对象仍然可以隐藏其内部状态。我看到的唯一真正的缺点是它是对象过载的轻微情况。

于 2010-07-29T10:46:52.980 回答