Аннотации - это хорошо или плохо?

Вурдалак

Продвинутый новичок
Не знаю причем "явные методы", если речь вообще шла о анемичности моделей, провоцирование анемичности доктрина-аннотациями и валидации входящих данных в модели без промежуточных форм. Поясни.
$user->setData($_POST) — это неявный метод, даже если ты делаешь какую-то валидацию $_POST.
$user->rename($newName), $user->ban($moderatorId), $user->confirmEmail() — это набор явных методов.
 

MiksIr

miksir@home:~$
$user->setData($_POST) — это неявный метод, даже если ты делаешь какую-то валидацию $_POST.
$user->rename($newName), $user->ban($moderatorId), $user->confirmEmail() — это набор явных методов.
И как в явных методах будет изменение карточки пользователя из админки? Или карточки товара?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Вас можно понять, только посидев подумав пару минут, и только со знанием многолетней истории этого диалога.
Вы бы хоть немного мысли в слова переводили.

$user->setData($_POST) - это кодогенерация, и у нее своя ограниченная сфера применения.
А как насчет $User = $UserFactory->createWithData($_POST); ?
 

fixxxer

К.О.
Партнер клуба
@grigori, либо код в этой factory обрастет лапшой из десятка if-ов вида "если пользователь создается админом, пометить email подтвержденным, иначе запросить подтверждение емейла", либо появятся методы типа $userFactory->createByAdminWithData($_POST) и просто переложишь пачку кода из одного места в другое, либо - если это все не нужно - "это кодогенерация, и у нее своя ограниченная сфера применения".
 

MiksIr

miksir@home:~$
@grigori, либо код в этой factory обрастет лапшой из десятка if-ов вида "если пользователь создается админом, пометить email подтвержденным, иначе запросить подтверждение емейла", либо появятся методы типа $userFactory->createByAdminWithData($_POST) и просто переложишь пачку кода из одного места в другое, либо - если это все не нужно - "это кодогенерация, и у нее своя ограниченная сфера применения".
А причем тут фабрика и то, кем создается пользователь?
 

MiksIr

miksir@home:~$
Вас можно понять, только посидев подумав пару минут, и только со знанием многолетней истории этого диалога.
Вы бы хоть немного мысли в слова переводили.
Ну главное мы понимаем ;) На самом деле я могу предположить ответ Вурдалака. Делаем $user->update($a, $b, $c) или еще лучше $user->update(UserUpdateRequest $r). Но вот становится ли модель менее анемична от замены 5-и сеттеров на один сеттер с 5-ю параметрами? А апдейт все-равно делатется через UserUpdateService.
 

Вурдалак

Продвинутый новичок
Ну главное мы понимаем ;) На самом деле я могу предположить ответ Вурдалака. Делаем $user->update($a, $b, $c) или еще лучше $user->update(UserUpdateRequest $r). Но вот становится ли модель менее анемична от замены 5-и сеттеров на один сеттер с 5-ю параметрами? А апдейт все-равно делатется через UserUpdateService.
Тебе не кажется, что в разговоре на тему CRUD нейминг играет существенную роль?
Конкретно в данном случае — решающую.
Ты метод действительно называешь просто «update»?
Я что, могу через этот метод поменять юзеру статус?
Могу его забанить?
Сменить ему дату регистрации?
Можно ли сменить пользователю пол?

Или же ты просто поленился перевести бизнес-глагол, который сам и используешь:
И как в явных методах будет изменение карточки пользователя из админки? Или карточки товара?
«Изменение карточки пользователя» — это не просто «апдейт», это может быть вполне себе бизнес-методом. Это, например, ChangeProfile. $user->changeProfile($profile). Под «изменением карточки» стоит понимать вполне определенную вещь (смена имени, даты рождения, локации и т.д.), здесь не должно быть возможности менять дату регистрации, id или статус «забанен/не забанен».

Но вот становится ли модель менее анемична от замены 5-и сеттеров на один сеттер с 5-ю параметрами?
$user->rename() — это не сеттер. $user->setName() — это сеттер, даже если они выглядит внутри идентично. Это называется семантическим различием.
Сеттер не имеет права обрастать логикой. Бизнес-метод — имеет.
Я могу в rename() начать хранить дату последнего смены имени, и не позволять менять его каждые 2 минуты.
Я могу при попытке переименовать во второй раз за час отправить имя на модерацию, как это сделано, по-моему, ВКонтакте.
Могу добавить ещё метод, который предназначен для смены имени модератором — без этих ограничений, естественно.
И хотя технически они ведут к одному тому же UPDATE users SET name = 'new name', они могут порождать разные события (UserChangedName, UserNameWasChangedByModerator) и иметь разную внутреннюю логику валидации.
С CRUD это становится неявным: у пользователя просто сменилось поле name. Кто его сменил, зачем, при каких обстоятельствах — модель не понимает. Она тупая, анемичная.

Даже если логики никакой нет, я реально не понимаю что мешает начать с правильного именования. Мы не апдейтим, мы «меняем карточку», блокируем, переселяем. Неужели говорить с бизнесом на одном языке — это «сложно»?
 
Последнее редактирование:

MiksIr

miksir@home:~$
Даже если логики никакой нет, я реально не понимаю что мешает начать с правильного именования. Мы не апдейтим, мы «меняем карточку», блокируем, переселяем. Неужели говорить с бизнесом на одном языке — это «сложно»?
$product->changeProduct()? $city->changeCity()? И не нужно про $city->rename(), нет у нас ренейма. Разве что только в сервсие не сравнивать - изменилось ли каждое поле модели и вызывать ->rename(), ->deactivate() и т.д.
 

Adelf

Administrator
Команда форума
$city->changeName(...) - повлечет за собой просто update в базу.
$city->changeCountry(...) - не только update, но и событие, обработчик которого пересчитает изменившееся население двух стран. По понятным причинам оно денормализованно обычно хранится.
Чего ты с очевидным споришь?
 

MiksIr

miksir@home:~$
$city->changeName(...) - повлечет за собой просто update в базу.
$city->changeCountry(...) - не только update, но и событие, обработчик которого пересчитает изменившееся население двух стран. По понятным причинам оно денормализованно обычно хранится.
Чего ты с очевидным споришь?
Извини, а с чем я спорю?
 

MiksIr

miksir@home:~$
В следующий раз выложи код в публичный доступ, если ты хочешь примеры прямо по твоему конкретному проекту.
Эм, какой код? Вообще речь шла о существовании простых проктов не сильно отличающихся от crud и допустимости для них послаблений, влроль до
Вот это самое оно. У C# Entity Framework есть все возможности юзать его как датамаппер и более-менее неанемично писать. Но они туда пихают аттрибуты к каждому свойству. Описывающие как это в базе данных будет лежать [Unique] так и [MaxLength] всякий. И самое страшное, что один и тотже атрибут, Required, MaxLength будет использоваться как для генерации таблицы базы данных, так и для валидации данных после HTTP запроса. И народ активно создаёт Entity прямо из HTTP запросов, минуя любую логику. Это очень вредная вещь.
или, только DDD, только хардкор?
 

Adelf

Administrator
Команда форума
@MiksIr, ты научился использовать микроскоп(Doctrine) и он тебе крайне понравился. И ты решил использовать его везде. И забиваешь им гвозди(crud-проекты,в которых ты можешь просто научить юзеров использовать adminer какойнибудь или сгенерить любой кодогенерилкой, что будет в разы дешевле - не ты ли недавно возмущался про время украденное у работодателя?).
 

MiksIr

miksir@home:~$
в которых ты можешь просто научить юзеров использовать adminer какойнибудь или сгенерить любой кодогенерилкой, что будет в разы дешевле - не ты ли недавно возмущался про время украденное у работодателя
А ты уверен, что научить юзеров пользоваться каким-то интерфейсом, придуманным программистом для программистов или изучить какую-то кодогенерилку, которая, впрочем, генерит интерфейс не лучше - будет дешевле для бизнеса (а не для программиста), чем взять готовые компоненты с удобными и красивыми интерфейсами на знакомой доктрине? ;) Я вот уверен в противоположном.
 

Вурдалак

Продвинутый новичок
речь шла о существовании простых проктов
CRUD — это сложно.
CRUD — это просто.
Закон Годвина на phpclub: любой спор заканчивается рассуждениями о простых и не очень проектах.
Вот и поговорили.
 

Adelf

Administrator
Команда форума
Ну я все-таки развлеку. Но наверно, это мой последний довод. Зато весомый. Я расскажу к чему приводит этот подход, который @MiksIr называет простым.
Давным-давно код для сайта devconf.ru @admin взял с какого-движка с прошлых работ. Там были какие-то заказы и его присобачили для билетов на конференцию. Чего-то подпилили и оно заработало.
Заказ - сумма, статус(request, done,cancel), etc.
Потом возникла необходимость обработать такой кейс. Фирма не успевает оплатить безналом, поэтому пишет гарантийное письмо, где обязуется оплатить. Эти неоплаченные участники должны попасть в списки(для столиков регистрации), но не должны иметь статус done чтобы отличать их от оплаченных. Как решили? Добавить статус guaranteed. А в код, где раньше была проверка $order->status == 'done', поменяли $order->status == 'done' || $order->status == 'guaranteed'.
Потом нужно было как-то обрабатывать бесплатных участников. Прессу, оргкомитет, участники от партнеров(нужно было в одном месте держать все, чтобы видеть количество обедов, которые надо заказать, и так далее). Реализовалось это в такую схему. Таких участников просили сделать заказ и прислать номер заказа(!) администратору. Он находил этот заказ, и делал сумму заказа равной нулю(ну чтобы отчеты по суммам не попортить) и проставлял новые статусы(press, orgkomitet, partner) заказу. Форма редактирования заказа в админке оставалась "простой", но остальной код усложнялся. Условия для списка участников менялись Иногда они вытаскивались SQL запросом, поэтому не везде можно было облегчить это перемещение условия в метод модели. Статус заказа был крайне интересным. request, done,cancel, guaranteed, press, orgkomitet, partner.
Плюс добавились еще express. Это те, кто не успевал оплатить, но обещал оплатить наличкой на регистрации. Ну понятно. Девконф с его текущим функционалом в данной модели был бы едким говнокодом.
Мне пришлось отойти от такого crud и сделать форму чуть менее простой.
https://drive.google.com/open?id=0B9wGRpcG-SQDelctck5ScWo2S3M
Создать отдельные модели для бесплатных участников(на форме старый вариант их создания, который попросили оставить. они сейчас выписываются скопом на конкретного участника в другом месте админки). Статус вернуть на место, чтобы он был понятным. Ну там видно в общем. Дизайн отстой, но на него всегда нет времени.

Основная мысль. Каждый описанный мною новый функционал был небольшим. Переписывать всю модель приложения ради него, не стоило бы. Бизнесу выгоднее было бы не переписывать. Да и девелопер не стал бы. Влом и т.д.
Получив же нормальную модель, приложение получает такой большой потенциал для развития, гибкость,что сложно описать. Сложно это понять, имея отстойную модель.
 

Вурдалак

Продвинутый новичок
Человек сидит за столом и кидает мусор прямо на пол, потому что мусорное ведро уже давно забито и очевидно, что кинуть на пол фантик намного проще, чем убрать всё вокруг, вынести мусор и пропылесосить.
Но если не доводить до такого и вовремя выносить мусор, то не будет такой жопы и будет приятно находиться в квартире.

И складывается впечатление, что сидеть в мусоре для некоторых присутствующих — это не проблема, которая требует решения. Для них это норма. А в крайнем случае можно просто сменить квартиру. Каждому своё.
 

MiksIr

miksir@home:~$
Ну я все-таки развлеку. Но наверно, это мой последний довод. Зато весомый. Я расскажу к чему приводит этот подход, который @MiksIr называет простым.
Давным-давно код для сайта devconf.ru @admin взял с какого-движка с прошлых работ. Там были какие-то заказы и его присобачили для билетов на конференцию. Чего-то подпилили и оно заработало.
Вот ты уделяешь как-то мало этой фразе. А она, по идее, в _бизнесе_ основная. Взяли, и оно заработало. Что было бы, если пришел бы кто-то и сказал "вы что, это же не гибко... вот через 5 лет вам там одно поле понадобится поменять, другое".... и вообще DDD!? О, с вероятностью 95% admin несколько лет бы еще записывал платежи в Экселе.
Это в общем единственное, что я хочу донести.
Основная мысль. Каждый описанный мною новый функционал был небольшим. Переписывать всю модель приложения ради него, не стоило бы. Бизнесу выгоднее было бы не переписывать. Да и девелопер не стал бы. Влом и т.д.
Это не так. Есть понятие технического долга, и бизнес его хорошо знает, ну, или должен знать. Причем часто он накапливается осознанно, ибо есть понимание того, что к тому моменту, как багаж станет тормозить - проект или совсем сдохнет или станет вообще о другом и для других, вплоть до другого общего языка.
 
Сверху