В Magento 2 вижу, что все DataObject наследуют \Magento\Framework\DataObject:
/**
* Universal data container with array access implementation
*
* @api
* @SuppressWarnings(PHPMD.NumberOfChildren)
* @since 100.0.2
*/
class DataObject implements \ArrayAccess
Но в этом классе куча ненужных методов (когда тебе нужны только геттеры и сеттеры), в т.ч. магических - это раз. И во-вторых чем лучше реализация геттеров и сеттеров через свойство-массив data? Не лучше ли просто делать приватные свойства и для них методы get/set?
Ниже набросал два варианта реализации DTO (второй как у мадженто, но без лишних методов)
class PropsDto
{
private string $strProp1;
/**
* @return string
*/
public function getStrProp1(): string
{
return $this->strProp1;
}
/**
* @param string $strProp1
* @return PropsDto
*/
public function setStrProp1(string $strProp1): self
{
$this->strProp1 = $strProp1;
return $this;
}
/**
* @return string
*/
public function getStrProp2(): string
{
return $this->strProp2;
}
/**
* @param string $strProp2
* @return PropsDto
*/
public function setStrProp2(string $strProp2): self
{
$this->strProp2 = $strProp2;
return $this;
}
/**
* @return string
*/
public function getStrProp3(): string
{
return $this->strProp3;
}
/**
* @param string $strProp3
* @return PropsDto
*/
public function setStrProp3(string $strProp3): self
{
$this->strProp3 = $strProp3;
return $this;
}
private string $strProp2;
private string $strProp3;
}
class ArrayDto
{
private array $data = [];
private const STR_PROP1 = "str_prop1";
private const STR_PROP2 = "str_prop2";
private const STR_PROP3 = "str_prop3";
private function getData($key)
{
return $this->data[$key] ?? null;
}
public function setData($key, $value = null): self
{
$this->data[$key] = $value;
return $this;
}
/**
* Getter for StrProp1.
*
* @return string|null
*/
public function getStrProp1(): ?string
{
return $this->getData(self::STR_PROP1);
}
/**
* Setter for StrProp1.
*
* @param string|null $strProp1
*
* @return void
*/
public function setStrProp1(?string $strProp1): self
{
return $this->setData(self::STR_PROP1, $strProp1);
}
/**
* Getter for StrProp2.
*
* @return string|null
*/
public function getStrProp2(): ?string
{
return $this->getData(self::STR_PROP2);
}
/**
* Setter for StrProp2.
*
* @param string|null $strProp2
*
* @return void
*/
public function setStrProp2(?string $strProp2): self
{
return $this->setData(self::STR_PROP2, $strProp2);
}
/**
* Getter for StrProp3.
*
* @return string|null
*/
public function getStrProp3(): ?string
{
return $this->getData(self::STR_PROP3);
}
/**
* Setter for StrProp3.
*
* @param string|null $strProp3
*
* @return void
*/
public function setStrProp3(?string $strProp3): self
{
return $this->setData(self::STR_PROP3, $strProp3);
}
}
Гонял в цикле, и первый вариант даже оказался быстрее процентов на 20
Кто-нибудь вообще может привести преимущества реализации через массив со значениями?
Простота реализации метода toArray и магические методы уже ни разу не аргумент, т.к. мы программируем на основе интерфейсов уже давно, а не реализаций. И для DTO в той же Мадженте есть тулзы преобразования в массив чисто на основе анализа get методов интерфейса.