Контейнер свойств (англ. property container) — фундаментальный шаблон проектирования, который служит для обеспечения возможности динамического расширения свойств уже созданного объекта класса.
Это достигается путем дополнительных свойств непосредственно самому объекту в некоторый "контейнер свойств", вместо расширения класса новыми свойствами.
Достоинства
Шаблон контейнер свойств позволяет легко и быстро придать приложению способность изменяться в процессе своего жизненного цикла и хорошо подходит для определённых типов приложений, в частности, для реализации возможности иерархии вложения. В некоторый случаях, без применения данного шаблона не удастся при возможности динамического расширения объекта инкапсулировать данные в объекте, что влияет на безопасность и надежность приложения.
Недостатки
При реализации контейнера свойств теряется строгая типизация. Интерфейс класса не полностью описывает содержание и, возможно, потребуется модифицировать интерфейс взаимодействия с классом, чтобы реализовать преимущества, полученные от добавленных атрибутов. Если используется сохранение объектов в базу данных, контейнер свойств требует написать реализацию для передачи данных из контейнера свойств объекта в таблицу. Использование контейнера свойств увеличивает сложность системы, вносит накладные расходы на потребление памяти приложением и частично снижает быстродействие при работе.
Пример реализации контейнера свойств на PHP
Объявим интерфейс PropertyContainerInterface
interface PropertyContainerInterface{
function setProperty($propertyName, $value);
function updateProperty($propertyName, $value);
function getProperty($propertyName, $value);
function deleteProperty($propertyName, $value);
}
Напишем реализацию интерфейса.
class PropertyContainer implements PropertyContainerInterface{
private $propertyContainer = [];
function setProperty($propertyName, $value){
$this->propertyContainer[$propertyName] = $value;
}
function updateProperty($propertyName, $value){
if (!isset($this->propertyContainer[$propertyName]))
{
throw new Exception("property {$propertyName} not found");
}
$this->propertyContainer[$propertyName] = $value;
}
function getProperty($propertyName, $value){
return $this->propertyContainer[$propertyName];
}
function deleteProperty($propertyName, $value){
unset($this->propertyContainer[$propertyName]);
}
}
Унаследуем реализованный класс контейнер с методами.
class BlogPost extent PropertyContainer{
private $title;
public function setTitle($title){
$this->title = $title;
}
}
Пример использования контейнера свойств.
$post = new BlogPost();
// присваиваем свойсво изначально объявленое в классе
$post->setTitle('Hello');
// присваиваем динамическое свойство объекту
$post->setProperty('view_count', 100);
$post->updateProperty('view_count', 200);
$post->getProperty('view_count');
$post->deleteProperty('view_count');