🐴
спасибо
Sergei
3) это уже чистая вкусовщина и опять же в каждом монастыре свои уставы ('best practices"), однако моя уверенность в том, что в коде важна читаемость - потому пропагандирую публичные методы (которые по сути API класса) выносить в самый верх, как наиболее интресные для читателя, а всякое приватное - прятать куда-то в подвал файла.
🐴
а у меня разве не так?
🐴
я вроде тому же правилу следовал
Sergei
final class RevisionRange
{
private $from;
private $to;
🐴
ну
🐴
это же перменные
🐴
их тоже в подвал?
Sergei
ну я как читатель в целом не сильно заинтересован как класс устроен внутри
🐴
получается, что она спользуется (например в конструкторе) выше, чем объявляется?
🐴
ок
🐴
я понял твою мысль
🐴
и в целом согласен
Sergei
в С++ я настоятельно настаиваю всю реализацию (приватные методы и данные) в низ файла убирать, а публичной API - наверх
🐴
но "у нас тут своя атмосфера", общепринятые правила диктуют, что переменные должны быть вверху
🐴
методы - да, публичные сверху
Sergei
да, я не спорю, best practices они есть и им лучше следовать (ибо это то что читатель ожидает)
Sergei
еще мне кажется что RevisionRange::__constructor и RevisionRange::between делают почти что одно и то же (или я упускаю опять же специфику)
🐴
так и есть
Sergei
возможно, between избыточен здесь - мне симпатична сама идея хорошо именованного метода between, подчеркивающего поведение, одноко вместе с тем RevisionRange в моем представлении означает ровно то же.
🐴
блин как же тяжело
🐴
пока тесты напишешь, десять раз переделаешь все
🐴
зато YAGNI постигается на раз )
Sergei
:)
Sergei
где-то там же рядом концепция bit decay
🐴
Ща как применю TDD
Anonymous
Порекомендуйте книжки для джанго
Anonymous
https://docs.djangoproject.com/en/1.10/
Эту?
Sergey
слишком много надо думать, хотя если подагоняться какое-то время будет чуть проще
Ale
Вот srp наверное последний принцип про который надо думать 🤔
Sergey
Sergey
иначе смысл теряется
Sergey
вообще я все думаю засеть таки написать цикл статей свой... у меня сейчас куча идей уже записаны
Ale
SRP - только про зоны ответственности объектов, декомпозицию и кохижен. Про "делайте интерфейсы" ни слова
O/C - тут интерфейсы уже полезны, но это разного рода стратегии, акторы и прочее...
LSP - в целом тупо правила как правильно интерфейсы делать что бы не грустить когда делаешь O/C или ISP
ISP - тут да, используй интерфейсы для того что бы изолировать зоны ответственности объекта когда тебе с точки зрения SRP выгоднее все держать в одном классе. Способ снижения связанности и только. Соблюдение ISP + SRP выводит баланс между coheasion и coupling
DIP - изоляция модулей, опциональное, позволяет тебе просто между несколькими модулями инвертировать направление зависимости тем самым снизив связанность
Ale
а главное - все это опционально, не надо на этом зацикливться. Все это должно приносить пользу и в итоге ты просто где-то живешь с чуть большей связанность а где-то где все плохо можешь ее снизить используя эти принципы
Sergey
Sergey
мысли твои из симфони румы сюда направили)
Ale
ага)
Sergey
ясно)
Rodion
Sergey
что читать хз... тут подойдет любая штука на тему agile mindset, lean, user story и т.д. Например
https://www.youtube.com/watch?v=6q5-cVeNjCE
Sergey
годная штука по декомпозиции в виде юзер стори + acceptance criteria
Sergey
по bdd конкретно есть следующие видосы:
https://www.youtube.com/watch?v=2EM4itu7j7I
Sergey
там 2 части, они вполне полезны
Ale
Ale
@Enleur кстати вот Грег Янг тут обмолвился про save в репозитории https://www.infoq.com/presentations/8-lines-code-refactoring
Ale
"его там не должно было быть"
guga
кстати, а почему вы пришли к orm?
guga
вам не кажется что это очень плохая идея
guga
если она делает что-то больше чем мапинг
Sergey
Sergey
да
Ale
Ale
Sergey
guga
и адский саппорт
guga
у вас orm генерит sql запросы?
Ale
Sergey
и адский саппорт
если ты про SELECT запросы - да, львиную долю генерит ORM, он неплохо это делает для простых вещей. А для сложных набросать свой SQL просто проще
Sergey
если коротко - ORM нужны для обработки маленьких бизнес транзакций. Если тебе нужны репорты - юзай SQL
Sergey
примерно вот так делаем запросы
public function getInvoiceByHashAndUserId($hash, $userId)
{
return $this->createQueryBuilder('i')
->select('i, o, u')
->leftJoin('i.order', 'o')
->leftJoin('o.user', 'u')
->where('i.hash = :hash')
->andWhere('u.id = :userId')
->setParameter('userId', $userId)
->setParameter('hash', $hash)
->getQuery()
->getOneOrNullResult();
}
guga
хм, в целом выглядит довольно неплохо
Sergey
guga
Sergey
guga
Скорее от незнания самого хибера, много проблем
guga
а в нём очень много неочевидных мест.
Ale
вот презенташка Янга как раз в тему
Sergey
ну да... в целом есть такая штука. Выше @mkusher как раз об этом кидал доклад Грега Янга