Образец творения: "Фабрика ублюдков", дополнительный завод Фабрики - PullRequest
0 голосов
/ 29 июля 2010

В настоящее время я пытаюсь выяснить, как лучше всего создать мои объекты в моем текущем проекте 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 с каким-либо конкретным бэкэндом, у меня должны были быть разные фабрики для каждого бэкэнда (например, база данных MySQL или файловый поток).Поэтому я бы перенес логику загрузки и инициализации на фабрики.Это, однако, будет работать, только если все поля в классе Special являются общедоступными для Factory.Однако они не должны быть общедоступными для остальной части приложения.

В C ++ я мог бы использовать друзей, чтобы обойти эту проблему.Также здесь о переполнении стека я читал почти на ту же тему, но применительно к C #.Он сказал, что я должен просто установить все поля общедоступными в классе Special и заставить Factory возвращать только интерфейс, который предоставляет методы и атрибуты, которые я хочу сделать общедоступными для приложения.Но так как PHP не поддерживает подсказки возвращаемого типа, я не могу вернуть только интерфейс, который реализует специальный класс.Другой способ, которым я придумал, - это на самом деле получить наследование SpecialFactory от класса Special, позволяющего получить доступ к закрытым и защищенным полям с фабрики.Это то, что я назвал «Фабрика ублюдков», поскольку фабрика наследует от своего собственного продукта.

Я хотел бы знать, может ли кто-нибудь из вас, ребята, придумать лучший способ добиться того, чего я хочу.Или я совершенно не в курсе, и процесс инициализации на заводе полностью запрещен?Мне интересно ваше мнение!

1 Ответ

1 голос
/ 29 июля 2010

Исходя из фона Java, как насчет добавления туда компоновщика?Этот застройщик может раскрыть свое состояние через открытые поля, на которых фабрика может строить.Как только сборщик будет завершен, передайте его вашему Специальному классу и позвольте ему загрузить свое состояние из сборщика.

Примерно так на вашем заводе (псевдокод):

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

Таким образомВаш Специальный объект все еще может скрывать свое внутреннее состояние.Единственный реальный недостаток, который я вижу, это небольшой случай перегрузки объекта.

...