Dmytro
@Vaderoff вы документацию пробовали читать?
Egor
Нет (
Dmytro
Так, пожалуйста, сделайте нам и себе такую услугу
Иван
ААААААААААААААААААААаааааааааааааааааааааааааааааааааааааааррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррррр!!!!!!!1111111111235
Иван
Бизнес-логика размазанная по куче контроллеров это жопа.
Egor
SiZE
Просто прочитай.
Egor
То есть мне нужно поместить это все в одну строку?
SiZE
Ты программист или экстрасенс? :)
Dmytro
Похоже не помогло, давай так:
Напишите, что именно вам надо
Egor
агрх, мне в школе учебники читать, так еще и дома доки к фреймворкам ((
Dmytro
Так вы сударь лентяй)
Egor
Так вы сударь лентяй)
Да вы правы. Но стараюсь не быть им. Ибо лентяй никогда не победит, а победитель не может быть лентяем.
Anonymous
Совсем какие-то простые вопросы спрашиваешь. Это ведь всё в доках есть.
Egor
Больше не буду смотреть на ютубе уроки (
Иван
Такая тема:
Есть юзеры. Есть "пакеты" (по аналогии с "пакетами минут и смс" т.е. цена, скидка, продолжительность действия и всякие там дополнительные плюшки). Есть заказы (включает в себя список товаров и услуг). Есть платежи (включают в себя пакеты, заказы, способ/статус оплаты и т.п.).
Логика с которой пакет присваивается юзеру довольно замороченная, плюс имеет свойство меняться. Примерный сценарий такой:
Юзер покупает подписку, при этом либо оплачивает её, либо обещает оплатить наличными/картой курьеру. В первом случае она сразу добавляется юзеру (либо продлевает срок действия текущей). Во втором не происходит вообще ничего до того момента, когда платёж заапрувит админ.
Далее она уже влияет на цены (даёт скидку), начисляет что-то на лицевой счёт (с него можно оплачивать всякое), да и много ещё на что влияет.
Кроме того, почти уверен, что когда-нибудь обязательно будет решено сделать возможность иметь несколько подписок одному юзеру и всячески извращаться с логикой их применения / добавления / активации.
При этом сейчас имеющаяся логика кое-как размазана по экшнам контроллеров и очень туго поддаётся чтению и правке.
Очевидно надо эту логику как-то в одно место собрать, да желательно отдельно от всякого там хранения/валидации. Но вот как лучше это сделать?
[удалена куча рассуждений на тему разных решений и их недостатков]
Иван
Наитупейший вариант: влепить в текущую ar-модель платежа пару методов, в которые эту логику и перетащить. В дальнейшем в отношении прочей логики поступать аналогичным образом.
Иван
Другой вариант это сделать какие-то отдельные модели, которые принимали бы из контроллеров уже готовые валидные ar-модели и делали бы с ними своё грязное дело. Далее любую выходящую за рамки "принять, проверить и записать" логику реализовывать только через такие вот отдельные модели.
SiZE
Такая тема:
Есть юзеры. Есть "пакеты" (по аналогии с "пакетами минут и смс" т.е. цена, скидка, продолжительность действия и всякие там дополнительные плюшки). Есть заказы (включает в себя список товаров и услуг). Есть платежи (включают в себя пакеты, заказы, способ/статус оплаты и т.п.).
Логика с которой пакет присваивается юзеру довольно замороченная, плюс имеет свойство меняться. Примерный сценарий такой:
Юзер покупает подписку, при этом либо оплачивает её, либо обещает оплатить наличными/картой курьеру. В первом случае она сразу добавляется юзеру (либо продлевает срок действия текущей). Во втором не происходит вообще ничего до того момента, когда платёж заапрувит админ.
Далее она уже влияет на цены (даёт скидку), начисляет что-то на лицевой счёт (с него можно оплачивать всякое), да и много ещё на что влияет.
Кроме того, почти уверен, что когда-нибудь обязательно будет решено сделать возможность иметь несколько подписок одному юзеру и всячески извращаться с логикой их применения / добавления / активации.
При этом сейчас имеющаяся логика кое-как размазана по экшнам контроллеров и очень туго поддаётся чтению и правке.
Очевидно надо эту логику как-то в одно место собрать, да желательно отдельно от всякого там хранения/валидации. Но вот как лучше это сделать?
[удалена куча рассуждений на тему разных решений и их недостатков]
бандлы )
SiZE
вообще сервисный слой упрощает работу
Иван
Со вторым вариантом немного не понятно, как, например, называть классы этих моделей. Ну допустим вот эта история с платежом, юзером, подпиской и опциональным админом. Что это? Платёж, юзер, подписка? Не ясно. А раз не ясно можно и божественный класс запилить.
SiZE
это прослойка между контроллером и AR в прямом его понимании или моделью
SiZE
тут подробней ответил slavcodev http://www.yiiframework.ru/forum/viewtopic.php?p=193207#p193207
SiZE
Для более точного понимания Фаулер "Архитектура корпоративных приложений"
SiZE
После сервисного слоя на самом деле мне захотелось большего.. но в компании сейчас я к сожалению не могу тратить время на это
SiZE
да может оно и не надо
Иван
Хм. То есть получается, я создаю, скажем, класс
ServicePackBuy
, в нём, скажем, два метода:
userMakePayment(User $user, Payment $payment)
и
adminConfirmedUserPayment(User $user, Payment $payment)
Или... Один метод:
go(Payment $payment)
в котором что-то типа
if($payment->status === Payment::STATUS_CONFIRMED) {
$user->pack = $pack;
....
}
Правильно я понял идею?
👀
SiZE
SiZE
если надо Payment::STATUS_CONFIRMED то вешаем события на PaymentInterface
Иван
Хотя, блин. Наверное этот BuyPackService Должен побольше методов иметь. На заказ пакета, на его оплату, на подтверждение/отмену админом. Или нет?
* Это чтобы можно было легко и просто менять всю эту логику, изменяя только этот класс и ничего более
Иван
👀
Мне кажется, что подписка может иметь статус активна или нет
Если пользователь платит сразу - сразу активируем, если нет - админ активирует
👀
Ну и, соответственно, в тех местах, где нужно проверять, есть подписка или нет, проверять, активна ли она
Иван
Проблема в том, что это надо придётся делать в _разных_ местах. И эта логика любит меняться.
Иван
Оно ведь сейчас так и есть: в одном контроллере что-то выставилось, в других что-то проверяется
👀
Можно, конечно, из говна и палок сделать ракету, но качество будет, сами понимаете, не айс
Если там всё так плохо, то лучше переделать
Иван
а когда надо что-то менять приходится по всем экшнам всех контроллеров лазить
Иван
ну вот я и выясняю как бы переделать
Иван
чтобы не сделать из говна говно
👀
Ну смотрите
Добавлять, активировать - думаю, понятно как
Добавлять на счет при активации - через события
Проверять - расширяем юзера методом getSubscriptions(), который должен возвращать только активные подписки
Ну и, если мы говорим об изменении цены, то в модели товара (например) делаем getPrice(), который проверяет подписку у пользователя, и возвращает цену с учетом скидки подписки
Dmytro
@Ivan_0x9d8e я бы сделал компонент, который бы заведовал всей сложной логикой транзакций, оплат и тд и покрыл бы его тестами
Компонент бы рабол с интерфейсами, которые модели бы реализировали
Dmytro
Надеюсь, не очень сумбурно написал
SiZE
Не понял.
сервис оплаты кидает событие (класс от Event).
передаем в событие все что надо
событие имплементирует интерфейс
вешаем на интерефейс слушателей
Dmytro
Поддерживать это не очень сложно, если тесты держать в порядке
SiZE
для полноты оборачиваем в транзакцию или ждем обработки события в переменной какой нибудь
Dmytro
Если делать на event-ах, будет нормальный IoC, но сложнее поддержка
Иван
Ну смотрите
Добавлять, активировать - думаю, понятно как
Добавлять на счет при активации - через события
Проверять - расширяем юзера методом getSubscriptions(), который должен возвращать только активные подписки
Ну и, если мы говорим об изменении цены, то в модели товара (например) делаем getPrice(), который проверяет подписку у пользователя, и возвращает цену с учетом скидки подписки
Непонятно как раз как добавлять/активировать.
В первую очередь потому, что это может разным образом происходить.
Ну и хочется видеть всю бизнес-логику в одном месте, ясно и просто, отдельно от всего прочего.
Dmytro
Можно будет в событиям из любого места добраться, вроде бы хорошо, но если проект будут делать долго и несколько людей - - может сойти на хлам
Иван
Не очень понимаю зачем тут события
Иван
Чем вызов метода не событие?
Dmytro
Вы слышали об Inversion of control?
Иван
Неа
Dmytro
Если нет, тогда лучше делайте один компонент
Dmytro
И там вся логика
Dmytro
Тесты написать будет просто
Dmytro
Главное делать все в одном месте
Dmytro
Как я понял, это для вас важно
Иван
Важно то важно, но и отсутствие божественных классов тоже важно
Dmytro
Тут одно с двух
Dmytro
Думаю, если у вас будет нормально покрыт тестами один мега-класс - - будет вменяемо
Иван
Думаю сейчас сделать класс, который будет заниматься исключительно процессом покупки пользователем пакета. Только не могу выбрать между тем, чтобы он вообще на любое действие с этим связанное дёргался или только в двух случаях.
Dmytro
Лучше на все
Dmytro
Но это лично моё мнение
Dmytro
Если уже хотите держать все в одном месте
SiZE
SiZE
те. пишем класс и рефакторим
SiZE
когда есть опыт рефакторинга меньше становится
SiZE
а может и больше )))
Egor
Рефакторинг - это?
Иван
Рефакторинг - это?
Строго изменение кода, без изменения его внешнего поведения. А так просто работа над его структурой и порядком.
who are you
рефакторинд в пхпшторме ничо не делает
who are you
я думал он мне код расставит красиво
who are you
а он тупо пробелы убрал и всё
who are you
😄
who are you
наверное я неправильео понимаю этот инструмкент
who are you
печатаю в темноте извиняюсь)