Куда переносить логику проверки валидности значения: Domain Object или Unit Of Work

Rammstein

PHPClub::News
Куда переносить логику проверки валидности значения: Domain Object или Unit Of Work

Существует такая система: Domain Object (его же можно назвать хранимым объектом; DO) отображается на БД через Data Mapper. При этом, дабы сократить количество обращений к БД, существует UnitOfWork, который следит за изменением всех DO и в конце транзакции в пакетном режиме закрепляет изменения в БД (одним большим запросом).

Коротко и грубо о принципе отражения DO на БД. У DO есть свойства, которые по схеме перекачёвывают в поля таблицы. Так вот, значение свойств требует предварительной проверки на валидностью (типа XSS и прочее). Проблема заключается в выборе места проверки полей. Есть два варианта:

а) В самом объекте в методе __set()
б) В UnitOfWork перед самым внесением изменений

Недостаток a) в том, что не сохраняется принцип Domain Model, т.к. потребуется отказаться от явного указания свойств. Так же я вижу определённые проблемы с производительностью (обращение через __get() потребует большего времени, чем прямое).

Но в отличии от a) , в б) сложнее контролировать изменения DO (потребуется каким-то образом сравнивать состояние в начале транзации и текущее, например, путём создания копии DO при инициализации)

Если это важно, то сам контроль валидности значения происходит в Field::is_valid($value). Вопрос только в том, когда это делать.

Из своих рассуждений:
Вероятно потребуется не более одного раза за транзакцию устанавливать новое значение свойства у DO, но считывать очень часто. Вопрос только в том, насколько обращение через __get() (при условии, что там только "return $this->fields[$name]") медленней прямого обращения к свойству.
Так же естественно, что если хранить копию DO, то расход памяти увеличится в два раза, да и операция сравнения двух объектов не самая быстрая.

Помогите решить: выделять проверку валидности свойства в UnitOfWork или же в DO::__set()
 

StUV

Rotaredom
imho - a)
- выносить проверки в UnitOfWork - совершенно кривое решение

задумываться об оптимизации будешь если появятся траблы с производительностью

(преждевременная оптимизация - зло / (c) не-помню-кто =)))

--
зы: в большинстве случаев при нормальной ОО-архитектуре - __set не нужен
 

Rammstein

PHPClub::News
У Фаулера именно get и set используется, но в Java у них иная реализация. Set в случае а) используется не только для валидации, но и для сообщения UOW об изменении объекта.

-~{}~ 01.06.06 22:23:

P.S> Тут, пожалуй, больше вопрос архитектуры, нежели оптимизации. В идеале DO должен выглядеть как набор полей и методов, потому как мапер именно для того и создан, что переносить "нормальные" объекты в БД, а не с перегружеными свойствами.
 

zerkms

TDD infected
Команда форума
проблема жизненная угу

имхо - в сеттерах при установке значения сразу валидировать и принимать решение
Так же естественно, что если хранить копию DO, то расход памяти увеличится в два раза, да и операция сравнения двух объектов не самая быстрая.
на эту фразу фаулер говорит, что:
"Although this adds overhead to the commit process, it allows a selective update of only those fields that were actually changed; ... This requires registration, but it supports selective update and greatly reduces the overhead of the copy if there are many more reads than updates."
то сам контроль валидности значения происходит в Field::is_valid($value).
этот момент чуток разверни, а то не совсем очевидно имхо, ибо ты сам же ниже говоришь что все значения у тебя хранятся в массиве - откуда тогда class Field знает как валидировать статическим методом конкретное значение.

и собственно где у тебя сейчас лежат правила валидации? в xml (или подобном хранилище) рядом с именами полей/мутаторов/акцессоров?
 

StUV

Rotaredom
У Фаулера именно get и set используется, но в Java у них иная реализация
в контексте пхп гет/сет используются в "магичексих" ситуациях, упрощающих разработку, но убивающих поддержку кода

стремление к универсализации за счет этих методов в итоге ни к чему хорошему не приводит

зы: но это только имхо...
 

zerkms

TDD infected
Команда форума
угу, сначала не обратил внимание, однако в доменной модели одним немаловажным моментом является определение мутаторов/акцессоров и как следствие работа с данными не через __get/__set а через __call
StUV
понятно, что те же яйца, однако в контексте ДМ совсем ничего противозаконного имхо нет, ибо сам по себе ДО представляет собой лишь контейнер для хранения данных, который в общем случае может быть одинаковым на весь проект
 

Rammstein

PHPClub::News
Автор оригинала: zerkms
этот момент чуток разверни, а то не совсем очевидно имхо, ибо ты сам же ниже говоришь что все значения у тебя хранятся в массиве - откуда тогда class Field знает как валидировать статическим методом конкретное значение.

и собственно где у тебя сейчас лежат правила валидации? в xml (или подобном хранилище) рядом с именами полей/мутаторов/акцессоров?
На счёт Field я, конечно, совсем не то написал. Реализации как таковой ещё нет. Правила валидации в самом Field храниться и будут, а уж откуда браться самим Field будут - вопрос второй, и, пока не решённый.

Автор оригинала: zerkms угу, сначала не обратил внимание, однако в доменной модели одним немаловажным моментом является определение мутаторов/акцессоров и как следствие работа с данными не через __get/__set а через __call
Как уже сказал ранее, всё что связано с проверками данных - содержится в логике Field.

Собстна провёл тест. В итоге:
0,000023 против 0,000028 сек
прямое получение значения и через __get() соответственно. Не особо на скорость повлияет. И то, я думаю, что дело здесь скорее в массиве.
Но вот с чистотой DO проблемы остаются... Но их не решить, наверное... разве что идти по пути UOW, но сравнение объектов будет гораздо дороже по ресурсам.
 

texrdcom

Новичок
Чисто интерестно где на практике применима такая схема работы с базой ?
 

robocomp

Новичок
я бы подумал так.
Если данные в объекты у меня приходят извне (например, из формы, или из какого-то унифицированного объекта Запрос), то я бы посчитал, что в ДО приходят хорошие данные и, соотвественно, UOW и DO забыли бы про проверки, зато про проверки вспомнил бы какой-нибудь кусок каркаса, отвечающий за:
а) выполнение конкретной команды (Command)
б) наполнение запроса данными
но вариант а) как-то приличней.

В случае, если в некоторые модифицирующие методы некоторых классов могут приходить хрен знает какие данные (ну, некому декларировать их корректность), тогда в этих методах __set() я бы и сделал проверку. Ну, если это вообще всё актуально, конечно
 
Сверху