Шаблон проектирования Декоратор

Статус
В этой теме нельзя размещать новые ответы.

deepslam

Новичок
Всем привет!

Реализовывая функционал в очередном проекте решил применить шаблон Декоратор и столкнулся с проблемой.

Суть ее в том, что я хотел динамически добавлять 1 одному (постоянному) объекту свойства.
Реализовал это с помощью шаблона Декоратор по схеме, описанной в книге Шаблоны проектирования и получилось что то вроде:

PHP:
$obj    = new Object();
$obj    = new ObjectDecorator($obj);
$obj    = new ObjectDecorator2($obj);
На выходе же получился совершенно новый объект, у которого всегда сохраняется только последнее свойство.
Т.е. выходит, что Декоратор не подходит в данном случае?

Я немного исправил код и получил нечто вроде:

PHP:
$obj    = new Object()
new ObjectDecorator($obj);
new ObjectDecorator2($obj);
Т.е. декораторы в своем абстрактном методое decorate изменяют мой объект.
Корректно ли так применять этот шаблон?

Каким образом Вы меняете свойства у объектов динамически? Именно у объектов, потому как если метод что то возвращает, а не изменяет свойства переданного ему объекта, то все прекрасно работает.
 

fixxxer

К.О.
Партнер клуба
Какой-то у тебя неправильный декоратор. В декораторах обычно:

PHP:
interface Foo { ... }
class FooDecorator implements Foo { ... }
class SomeClass extends FooDecorator { ... }
Поясни что ты сделать-то хочешь. Судя по всему тебе нужно подобие миксинов. Посмотри behaviors в yii тогда. Или трейты в php 5.4.
 

AmdY

Пью пиво
Команда форума
deepslam
тебе нужно в FooDecorator определить магические методы __get, __set, __call, чтобы они дёргали методы из оборачиваемого объекта.
 

Redjik

Джедай-мастер
Поправьте меня, если ошибаюсь, но этот Пэттерн больше подходит для яп где объект остается в памяти продолжительное время.
 

deepslam

Новичок
Какой-то у тебя неправильный декоратор. В декораторах обычно:

PHP:
interface Foo { ... }
class FooDecorator implements Foo { ... }
class SomeClass extends FooDecorator { ... }
Поясни что ты сделать-то хочешь. Судя по всему тебе нужно подобие миксинов. Посмотри behaviors в yii тогда. Или трейты в php 5.4.

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

Поясню, что хочу сделать. На самом деле это больше любопытство, но все же.

Есть объект запрос к базе, по умолчанию он возвращает SELECT * FROM нужная таблица

Я хочу его декорировать, добавляя условия выборки с помощью метода addWhere, но у меня изменяется только предыдущий объект, вот, как то так.

deepslam
тебе нужно в FooDecorator определить магические методы __get, __set, __call, чтобы они дёргали методы из оборачиваемого объекта.

Да, это отличная идея! Спасибо огромное за наводку!
 

Redjik

Джедай-мастер
У тебя на выходе всегда получается строка с запросом к базе.

От этого и пляши.

Зачем декорировать обьект, когда тебе просто нужно изменять строку.
Обычно делают так - созадют массив параметров, и перед query все это дело валидируют и собирают.
 

deepslam

Новичок
Ну да, просто мой объект еще кучу всего делает =) Да, надо будет рефакторить ))))
 

deepslam

Новичок
Не ))) Про кучу я погорячился, он выполняет лишь возложенную на него обязанность, строит запрос и получает постраничку, если она нужна )))
Я знаю, что нужно разделять обязанности классов )))
 

zerkms

TDD infected
Команда форума
Какой-то у тебя неправильный декоратор. В декораторах обычно:

PHP:
interface Foo { ... }
class FooDecorator implements Foo { ... }
class SomeClass extends FooDecorator { ... }
В декораторах обычно ещё и AbstractDecorator, от которого наследуются частные
 

alekciy

Новичок
препареды рулят, но не всегда, например валидный email
Ну пример с email это пример валидации строки, а не запроса. Хотя и это силами СУБД решаемо. В postresql, к примеру, через CHECK(). При этом не важно, какой код работает с базой, важно, что данные в поле с такой проверкой всегда будут корректные (конечно, если регулярка в check-е прописана корректно). В конечно итоге данные то у нас находятся не в коде, а базе, поэтому вынести валидацию именно на этот уровень вполне возможно. Если завтра в проект приходит новичок, забывает загнать данные в валидатор и пишет напрямую в базу, то запрос завершиться ошибкой. Если бы валидатор был в коде, то СУБД бы такой запрос отработала, тип поля же тестовой.
 

Redjik

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

alekciy

Новичок
Спорный вопрос, от части я согласен, что можно все на базу перенести, но вот нужно ли.
С каких пор СУБД боится задачи для которых была спроектирована? В обычном приложении INSERT-ов сильно меньше, чем выборок, кои кстати в нормально приложении лежат в кэше. Кроме того схему с репликацией еще ни кто не отменял. Так что вопрос железа даже не стоит, железо сейчас шустрое и достаточно дешевое, особо сравнивая с ЗП разработчика.

А вот человеку, причем любой квалификации свойственно ошибаться (кроме того всегда есть вариант работы с базой напрямую в обход движка). Просто квалифицированные разработчик делают это реже. Да и где их взять, квалифицированных то. На мелких задачах из пушки по воробьям. Приведенный пример с валидацией мыла пишется один раз при создании таблицы и работает, работает, работает. Вне зависимости от степени усталости, настроения, квалификации. И не ошибается при этом. Поэтому я придерживаюсь принципа, что любая задача которую экономически выгодно автоматизировать должна быть автоматизирована.
 

Redjik

Джедай-мастер
Опять же согласен, но!

Что у нас с повторяемостью кода?
Продолжаем разрабатывать пример с email.
(Да, и я на данном этапе развития, все сравниваю с колокольни Yii).

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

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

Для приложений на 1-3 человека при разработке в 2-3 месяца (и почти без дальнейшей поддержки) - игра не стоит свеч.
А таких приложений 99процентов.
 

Redjik

Джедай-мастер
+ как делать вывод ошибки валидации
на каждый кастомный тип (email) делать свой эксепшен?
опять то на то и выходит.
 

Ragazzo

TDD interested
Иван Redjik Матвеев
следующий этап,после валидации в БД, будет пихать в поле типа text строки php кода, и потом прогонять их через eval :D PROFIT!!!
 

Redjik

Джедай-мастер
Зря смеешься - сниппеты modx так и работают =)))

ЗЫ. внезапно! обнаружили уязвимость в этом разрабы =)))

ЗЫЫ. само собой тут не о валидации я наоффтопил
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху