Pull to refresh

Comments 15

Очень приятно что метод validate возвращает обьект а не изменяет состояние валидатора.
Очередная хрень в стиле PHP4. Почему бы не использовать нормальную концепцию MultiException?
Исключение, которое является коллекцией исключений. В PHP это делается двумя пальцами.
Вы избавляетесь от безумия вроде ->errors() и получаете полный контроль над ошибками.
Во первых чисто логически результат валидации это не исключительное событие. То что вы говорите это то же самое что если бы strpos() бросал исключение если субстрока не найдена.

Во вторых, чисто технически исключения гораздо прожорливее и медленнее так как включают в себя трейс и кучу инфы. Никто не занимается оптимизацией работы исключений так как предполагается что они не будут бросаться по чем зря, поэтому использовать их в валидации уже стрелять себе в ногу.
Господь с вами. Какое «прожорливее»? Какое «медленнее»? Когда вы последний раз упирались по производительности именно в PHP-код, а не в базу, память, свои кривые руки?

Результат валидации — это или true или false. А вот что вызвало этот результат — вполне себе исключение. То есть ОЖИДАЕМОЕ и ПРЕДВИДИМОЕ нами событие.
Результат валидации данных на наборе правил — это список (возможно пустой) невыполняющихся правил. $validator->isDataValid() лишь обёртка для empty($validator->getErrors()).

Разработчик валидатора точно знает, что его основная задача вернуть список ошибок. И исключения он бросает, когда встречается с ситуацией, которую он предвидел, но не знает как с ней поступать — например, синтаксически некорректные или логически противоречивые правила, тип данных, которые он не знает как валидировать и т.п. Исключения должны бросаться в общем случае, когда не знаешь как поступать в той или иной ситуации. Разработчик валидатора должен знать как поступать в случае нарушения правила — добавить этот случай в список. Если какого-то клиента не интересует список, интересует только факт, если он знает только как быть, если ошибок нет, но не знает как быть, если ошибки есть, то он может сам бросить исключение.
исключения он бросает, когда встречается с ситуацией, которую он предвидел, но не знает как с ней поступать


Разумеется, вы ошибаетесь.
Но это, видимо, тема отдельной статьи.
Исключения — это не про валидацию в общем случае. Штатная обязанность валидатора — вернуть клиенту список ошибок. Что с этим списком делать — дело клиента. Может проигнорировать запрос, может отдать список ошибок своему клиенту, может кинуть исключение, может выполнить запрос, залогировав ошибки, может выполнить запрос в песочнице, может выполнить запрос, вызвав на адрес пользователя группу захвата — не валидатору решать исключительная ситуация ошибки в данных или нет. В общем случае — штатная, обычно лишь предусматривающая другую или дополнительные ветки обработки.
Список ошибок — это коллекция исключений, возникших при валидации. Зачем же придумывать велосипед в стиле ->errors(), если есть нормальная объектная модель для этого?
Это не нормальная модель, как минимум она избыточна — зачем мне в результате валидации данных трейсы с указанием в какой строке валидатора обнаружилась ошибка?
Такой подход неизбежно устарел в мире API и REST, все чаще приходиться работать с документообразными запросами со сложной структурой. Validate с самого начала был спроектирован как раз чтобы справляться с такими задачами.

Имха со шпагой на перевес:
1: Validate с самого начала был спроектирован для работы только с FullREST.
2: Километр бизнес логики и 2 километра ФЛК убьет насмерть всю красоту и простоту.
Я работал с моделью, на которую было наложено 114 требований (отличных от размера или нахождения в списке) по валидации данных. + были требования по оптимизации производительности всего этого добра, т.к. данные могли импортироваться, и в немалом количестве. И требования менялись регулярно. Это был мой маленький персональный ад.
При количестве не структурируемых требований порядка сотни и больше (даже если они касаются только валидируемого объекта, не требуют, например, проверки в хранилище, что число членов агрегата не должно быть больше 10) и жесткими требованиями к производительности, красоты достичь обычно очень сложно. Или код — «плоский», с кучей вложенных ветвлений, но быстрый, или красивый, но медленный. Под красотой понимается, прежде всего, простота и скорость внесения изменений (включая добавление и удаление) в правила валидации.

Исключение — декларативное описание правил на DSL (вплоть до описания самим бизнесом без привлечения разработчиков) и генерация страшного, но быстрого кода, самое позднее, при первом запросе на проверку соответствия данному набору правил, а лучше при деплое новой версии набора правил.
Исключение — декларативное описание правил на DSL (вплоть до описания самим бизнесом без привлечения разработчиков)

Если честно, не встречал, но быстрое ознакомление с темой не до конца раскрыло проверки в хранилище. Да и отдавать на откуп бизнесу(? представителю заказчика) как? Ведь в идеальном мире мы должны проверить все входные параметры и недопустить исключения из-за ограничения проверки внешнего ключа. И т.д. и т.п. И выдать на все это нормальные предупреждения. Что требует как минимум знаний о всех связанных данных, помимо требований.
Или код — «плоский», с кучей вложенных ветвлений, но быстрый, или красивый, но медленный.

Т.е. варианта получается 3:
1. Проверок мало или требований по производительности не выставляется — пользуемся разными валидаторами.
2. Проверок много и есть требования по производительности — пишем быстрое спагетти.
3. Проверок очень много и пишем свои велосипеды с преферансом и гимназистками. И пофиг на потерю производительности по сравнению со спагетти, в этих экскрементах хоть как то надо разбираться.
Я в своё время писал для этих целей либу: AMatch (часть 2) с более коротким синтаксисом. Но код там очень несовременный.
Sign up to leave a comment.

Articles