Заводская модель подходит? - PullRequest
1 голос
/ 06 августа 2010

Ну,

У меня есть проблема (хорошо, никакой реальной проблемы, но я хочу попробовать что-то новое) с созданием объектов.На самом деле у меня есть несколько заказов, которые содержат список элементов заказа.

Эти элементы заказа используются и распространяются во всем приложении, и мне нужен способ их создания.Основная проблема в том, что я хочу иметь возможность создавать эти объекты разными способами.

На самом деле я делаю это в конструкторе классов и проверяю, задан ли аргумент.(Я использую php, поэтому нет никакой поддержки перегрузки от языка, как вы наверняка знаете:))

Простой и быстрый пример

class foo {
    protected $_data=null;
    public function __contruct($bar){
        if (is_array($bar)){
            $this->_data=$bar;
        }
        else {
            $dataFromDb=getDataFromDatabase
            $this->_data=$dataFromDb;
        }
    }
}

В любом случае, если я хочу создатьмой объект, предоставив другой тип параметра, скажем, xml-документ, инкапсулированный в строку, мне нужно поместить все эти вещи в мой конструктор.Если процесс создания объекта более сложный, мне в конечном итоге нужно создать отдельный метод для каждого типа, который я хочу инициировать.Но этот метод вызывается только при создании этого специального типа.(Я думаю, у вас есть проблема:))

Еще одна проблема приходит на ум: если мне нужно больше параметров в конструкторе для создания конкретного объекта, я должен изменить весь мой код, потому что изменился конструктор.(Хорошо, я могу дать ему все больше и больше параметров и работать со значениями по умолчанию, но это не то, что я действительно хочу).

Поэтому мой вопрос: какой шаблон подходит для этой задачи, чтобы решить мое создание конкретногообъект.Я думал о создании фабрики для каждого способа, которым я хочу создать конкретный объект.Но я не уверен, является ли это общим решением для решения такой проблемы.

Ответы [ 2 ]

2 голосов
/ 06 августа 2010

ЕСЛИ бы изменилась только сигнатура конструктора, я бы сделал это так (как универсальный конструктор Zend Framework):

class foo {
  // params

  public function __construct($options = null)
  {

    if(null !== $options)
    {
       $this->setOptions($options);
    }
  }

  public function setOptions(array $options){

    foreach ($options as $name => $value){
      $method = 'set' . $name;
      if(method_exists($this, $method)
      {
         $this->$method($value);
      }
   }

   return $this;
  }
}

И это означает, что все ваши параметры конструктора являются элементами массива с именованными ключами, и все, что вы хотите использовать в этом массиве во время инициализации, для которого вы создаете установщик, а затем его автоматически вызываете. Обратной стороной является отсутствие эффективного хинтинга в IDE.

С другой стороны, если вы хотите иметь определенные конструкторы, тогда я мог бы пойти с фабрикой, но все еще использовать тот же подход:

class foo {

  public static function create($class, $options)
  {
     if(class_exists($class))
     {
        $obj = new $class($options);
     }
  }
}

Конечно, вы можете альтернативно использовать отражение PHP, чтобы определить, как вызывать конструктор, а не просто вводить произвольный аргумент массива.

1 голос
/ 06 августа 2010

Вы можете просто сделать его фабрикой с необязательными параметрами:)

class Example_Factory
{
    public static function factory($mandatoryParam, $optionalParam = null)
    {
        $instance = new self;
        $instance->setMandatory($mandatoryParam);

        if ($optionalParam !== null) {

            $instance->setOptional($optionalParam);
        }

        return $instance;
    }

    public function setMandatory($in)
    {
        // do something....
    }

    public function setOptional($in)
    {
        // do some more...
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...