Как «красиво» проинициализировать свойство объекта? Заранее извиняюсь за глупый вопрос, но меня терзают смутные сомнения что я делаю что-то не так, есть такой случай:class Product {
//Some properties
//....
// \Models\OptionsInterface
protected $options;
// \Models\PriceInterface
protected $price;
protected $type;
public function setOptions($options)
{
if($this->type == ...some_condition_a && ...next_condition_a...)
{
$this->options = $this->factory->make('OptionsA', $options);
}
elseif($this->type == ...some_condition_b && ...next_condition_b ..)
{
//Some options logic
$options = ....
$this->options = $this->factory->make('OptionsB', $options);
}
//Также объект может и не иметь опций, в этом случае
//$this->options = null по-дефолту
}
public function setPrice($price)
{
$this->price = $this->factory->make('Price', $price);
}
}
class ConcreteProduct extends Product {

public function setOptions($options)
{
if($this->type == ...some_condition_a && ...next_condition_a...)
{
//Some options logic
$options = ....
$this->options = $this->factory->make('ConcreteOptionsA', $options);
}
elseif($this->type == ...some_condition_b && ...next_condition_b...)
{
//Some options logic
$options = ....
$this->options = $this->factory->make('ConcreteOptionsB', $options);
}
}
public function setPrice($price)
{
if($this->type == ...some_condition_a)
{
//Some price logic
$price = ...
$this->price = $this->factory->make('ConcretePriceA', $price);
}
elseif($this->type == ...some_condition_b)
{
$this->price = $this->factory->make('ConcretePriceB', $price);
}
else
{
$this->price = $this->factory->make('Price', $price);
}
}
}
//Работа с объектом осуществляется в таком роде
$product = new ConcreteProduct();
$product->setOptions($data['options']);
$product->setPrice($data['price']);
Проблема заключается в инициализации свойства $options и $price, количество наследников Product и типов $type может в будущем увеличиться, в следствии чего свойство $options будет иметь множество реализаций. Плодить наследников Product по типам также не очень хочется, как и городить кучу ветвлений. Есть идея создать фабрику для опций, но вот как описать логику выбора нужного класса... еще есть идея создать билдер для продуктов в зависимости от типа, но тут тоже есть сомнения...уже совсем запутался((
Заранее большое спасибо))

21 Авг 2019 в 07:07
164 +1
0
Ответы
1

Для инициализации свойства объекта таким способом, как вы описали, действительно можно использовать фабрику. Однако, чтобы упростить логику выбора нужного класса, можно также рассмотреть использование шаблона проектирования Стратегия.

Вы можете создать интерфейс, например, OptionsBuilderInterface, который будет иметь метод buildOptions($options). Затем реализовать этот интерфейс в различных классах, представляющих конкретные стратегии построения опций (например, OptionsABuilder, OptionsBBuilder и т.д.).

Затем в классе Product можно добавить свойство $optionsBuilder, и в методе setOptions использовать стратегию для инициализации опций:

class Product {
protected $options;
protected $price;
protected $type;
protected $optionsBuilder;
public function setOptions($options) {
if($this->optionsBuilder) {
$this->options = $this->optionsBuilder->buildOptions($options);
} else {
$this->options = null;
}
}
public function setPrice($price) {
// логика инициализации цены
}
public function setOptionsBuilder(OptionsBuilderInterface $optionsBuilder) {
$this->optionsBuilder = $optionsBuilder;
}
}

Затем, при создании экземпляра Product или ConcreteProduct, вы можете установить нужный строитель опций:

$product = new ConcreteProduct();
$product->setOptionsBuilder(new ConcreteOptionsABuilder());
$product->setOptions($data['options']);
$product->setPrice($data['price']);

Таким образом, вы сможете гибко добавлять новые реализации стратегий построения опций, не изменяя основной логики класса Product.

20 Апр в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 84 706 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир