Скажем, у меня есть следующий простой класс
<?php
class Variable
{
private $variableName;
private $variableValue;
public function __construct($name, $value)
{
$this->variableName = $name;
$this->variableValue = $value;
}
}
Я храню объекты Variable в коллекции следующего класса Collection.
class Collection
{
private $items = array();
public function addItem($obj) {
// Code for adding an item
}
// Other methods delete, sort, filter, etc
}
Кроме того, допустим, я использую очень несовместимый API для импорта множества имен и значений переменных. API возвращает JSON, но это действительно может быть что угодно.
Я говорю, что API несовместим, потому что в зависимости от вашего URI объект Variable может возвращать данные $raw в следующем формате:
{
"variables" : [
{
"name" : "variable_one",
"value" : "foo"
},
{
"name" : "variable_two",
"value" : "bar"
}
]
}
Или данные $raw могут быть в следующем формате:
{
"dataObject" : {
"variable_one" : "foo",
"variable_two" : "bar"
}
}
Кроме того, этот API все еще развивается, и я могу предвидеть, что они внесут непредсказуемые изменения в формат переменных данных $raw в будущем.
Вот мое текущее решение для использования данных $raw для получения коллекции объектов Variable:
<?php
// Turn JSON into stdObject
$variableData = json_decode($raw);
// Collection object to hold the variables
$variables = new Collection()
if ( property_exists($variableData, 'variables') ) {
foreach ( $variableData as $variable ) {
// Use for the first type of JSON
$variables->addItem(
new Variable($variable->name, $variable->value)
);
}
} else {
foreach ($variableData as $key => $value) {
// Use for the second type of JSON
$variables->addItem(new Variable($key, $value);
}
}
Проблема с этим решением заключается в том, что если конструктор переменных становится более сложным или количество различных форматов $raw может расти, это решение превращается в большой беспорядок.
Если Variable становится все сложнее и требует VariableFactory, мне нужно будет создать отдельную фабрику для каждого типа входа $raw. Если количество типов входных данных $raw растет, приведенный выше код превращается в большой беспорядок из операторов if и elseif.
Есть ли хороший шаблон проектирования, который я могу использовать для различных входных данных $raw для создания Collection объектов Variable?






Чтобы избежать путаницы с операторами if, вы можете использовать шаблон Visitor. По сути, каждая ветвь оператора if оборачивается функцией. Каждая функция принимает два аргумента: «инструкцию» и объект. Если функция «распознает» инструкцию, она что-то делает с объектом. В противном случае он молча возвращается.
Вы можете создать массив этих функций «посетителей» и перебирать их в цикле для каждого элемента ваших входных данных.
Это упрощенное объяснение (я печатаю на телефоне), но, надеюсь, оно укажет вам правильное направление.