флейм о трейтах

keltanas

marty cats
Если бы была возможность ограничить (принудить) использование трейта только в указанном(ых) интерфейсе(ах), жизнь была бы лучше. Или как вариант - возможность реализации трейтом интерфейса. А иначе получается программирование на слишком непрозрачных соглашениях.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Окей, а можно конкретный пример? Почему нельзя было сделать абстрактный класс?
Потому что в php нет множественного наследования. Иерархия абстрактных классов не катит - есть, скажем, три интерфейса, и наследники могут реализовывать любой их набор.

Такое ощущение, что тут нарушение моего любимого SRP.
Возможно, чуточку есть, но иные решения выглядят оверинжинирингом.
 

fixxxer

К.О.
Партнер клуба
Если бы была возможность ограничить (принудить) использование трейта только в указанном(ых) интерфейсе(ах), жизнь была бы лучше. Или как вариант - возможность реализации трейтом интерфейса. А иначе получается программирование на слишком непрозрачных соглашениях.
Согласен - это бы было идеально. Но в принципе, код выглядит так, что в голову не придет использовать эти трейты иначе.
 

Вурдалак

Продвинутый новичок
Потому что в php нет множественного наследования. Иерархия абстрактных классов не катит - есть, скажем, три интерфейса, и наследники могут реализовывать любой их набор.
Да, но опять-таки, если ты можешь реализовать самодостаточный трейт, то скорее всего тут нарушение SRP. 3 несвязанных ответственности.

В общем, трейты — это говно. Rejection git hook, bye-bye.
 

fixxxer

К.О.
Партнер клуба
Строго говоря, да (не самодостаточные, но в принципе, можно сделать таковыми), но в отсутствие generics и перегрузки методов при декоспозиции получатся фабрики с пачкой instanceof, что меня не радует совершенно.
 
Последнее редактирование:

hell0w0rd

Продвинутый новичок
Вурдалак, любое шаблонное поведение можно завернуть в трейт и реюзать, где нужно. Например синглтон. Я использую трейты с популярными свойствами для сущностей доктрины. https://github.com/nkt/translate-bundle/blob/master/src/Behavior/Translatable.php - или вот еще пример. По другому это сделать не реально, без еще большего говнокода.
 

Вурдалак

Продвинутый новичок
hell0w0rd, так я говорю про best practice и правильность с точки зрения теории. Пример с Singleton'ом никак не может быть в пользу трейтов, потому что сам по себе Singleton — это ущербный паттерн.

По поводу «популярных свойств» — это отдельная песня. Если твоя сущность просто представляет из себя набор сеттеров и геттеров, то ты получаешь anemic model. Если ты таким образом пытаешься избавиться от copy-paste, то возможно ты тоже что-то делаешь не так. Ты пытаешься пойти на избавление от copy-paste в ущерб модели. Уже тот факт, что от сущности к сущности могут несколько различаться требования (мы это уже как-то обсуждали), а ты не сможешь эти требования удовлетворить, говорит о том, что ты что-то делаешь не так.

Если рассматривать конкретный пример с переводом, то у меня есть некоторые сомнения относительно «правильности» нахождения переводов в модели: это скорее presentation layer в большинстве случаев. Т.е. всем насрать на перевод с точки зрения бизнес-логики, это нужно исключительно юзеру для взаимодействия с интерфейсом: на китайском он может ничего не понять, хотя логика одинаковая.

Если тебе трейты таким образом спасают жизнь — это окей. Возможно, это прагматично. Удобно. Появляется время выпить пива вместе с @AmdY после работы. Но я не вижу примеров правильного использования трейтов с точки зрения теории.
 
  • Like
Реакции: AmdY

Absinthe

жожо
Возможно, это прагматично. Удобно. Появляется время выпить пива вместе с @AmdY после работы. Но я не вижу примеров правильного использования трейтов с точки зрения теории.
Теория теорией, но повышение производительности разработчика влияет на стоимость и срок проекта. Это практика.
Если отхождение от теории позволяет повысить производительность, то надо отходить от теории.
 

Вурдалак

Продвинутый новичок
Меня раздражает такое оправдание говнокоду. Я в своей жизни работал над 2-мя большими проектами с тонной бизнес-логики. Мне регулярно приходиться проводить анализ существующих бизнес-требований. Это занимает 80% времени, написание кода — это хрень, которая у меня почти ничего не отнимает. Повышение производительности путём говнокода всегда ведёт к будущим проблемам при расширении проекта, при сильном изменении требований. Я не хочу реверсить логику из старого говнокода. Я регулярно вижу примеры кода, с которыми у меня бы не возникло проблем, если бы изначально люди следовали теории.

Ваши проекты на всяких Laravel ещё молодые. Вот что будет с ними лет через 5, если они интенсивно поддерживаются группой > 10-15 разработчиков, я бы посмотрел.
 

Absinthe

жожо
Меня раздражает такое оправдание говнокоду. Я в своей жизни работал над 2-мя большими проектами с тонной бизнес-логики. Мне регулярно приходиться проводить анализ существующих бизнес-требований. Это занимает 80% времени, написание кода — это хрень, которая у меня почти ничего не отнимает. Повышение производительности путём говнокода всегда ведёт к будущим проблемам при расширении проекта, при сильном изменении требований. Я не хочу реверсить логику из старого говнокода. Я регулярно вижу примеры кода, с которыми у меня бы не возникло проблем, если бы изначально люди следовали теории.

Ваши проекты на всяких Laravel ещё молодые. Вот что будет с ними лет через 5, если они интенсивно поддерживаются группой > 10-15 разработчиков, я бы посмотрел.
Ну приехали. Тебе не кажется, что кроме крупных кровавоэнтерпрайзных проектов существуют и другие?
Я сам сейчас пишу на симфони, понимая, что для энтерпрайза вариантов то больше и нет, но большинство проектов, которые делают люди, в эти рамки не вписываются.

Инструмент нужно выбирать под задачу. И для большинства задач симфони - плохой выбор.
 

hell0w0rd

Продвинутый новичок
Вурдалак, ну автор поста про DRY как обычно взял простейший вариант, который совсем не о проектах с тонной бизнесс-логики.
Банально у каждой сущности есть id и каждый раз нужно ее заного прописывать. С этим ничего не поделаешь.
Ну и о примере автора - у меня есть в коде очень похожие сущности и этот код я выношу в трейты, как только он начинает повторяться.
При работе с базой очень часто требуется множественное наследование, ибо много похожей логики.
На вскидку у меня в проекте сейчас 3 трейта от которых невозможно отказаться без дублирования кода - Translatable, Timestampable, Coordinatable, ну и Column\Id.
Если твоя сущность просто представляет из себя набор сеттеров и геттеров, то ты получаешьanemic model.
А с доктриной по другому нельзя. У меня есть методы, фильтрующие коллекции и на этом все, остальное тупые геттеры и сеттеры, которые приходится генерить php-stormом, но поддерживать-то мне.
 

Вурдалак

Продвинутый новичок
hell0w0rd, я не вижу проблемы написать одинаково выглядящий getId() в разных сущностях. Я скорее уделю внимание тому, а какой тип нужен идентификатору, а не выделить ли отдельный класс под него (FooId).

А с доктриной по другому нельзя
Почему?
 
Последнее редактирование:

hell0w0rd

Продвинутый новичок
Вурдалак, Потому что нужно так и так написать value-object с гет/сет-ерами, а на него логику накручивать.

Если нужен особый тип идентификатору - никто не спорит, но в 90% случаев нужен unsigned int и getId метод. Не говоря уже о шаблонных created_at, updated_at
 

hell0w0rd

Продвинутый новичок
Вурдалак, ты троллишь, или я реально чего-то не понимаю?) В доктрине по умолчанию для ленивых обращений к базе используются прокси-объекты, что делает невозможным создание public-свойств
 

fixxxer

К.О.
Партнер клуба
Ваши проекты на всяких Laravel ещё молодые. Вот что будет с ними лет через 5, если они интенсивно поддерживаются группой > 10-15 разработчиков, я бы посмотрел.
Без регулярного рефакторинга любой проект за 5 лет превращается в говно.
 

Вурдалак

Продвинутый новичок
Без регулярного рефакторинга любой проект за 5 лет превращается в говно.
Чтобы рефакторить, нужно понимать, как делать правильно, в какую сторону менять код. Более того, чтобы рефакторить, нужно чётко понимать текущие бизнес-требования, которые могут уже как-то образом быть разманы или даже утрачены (в том смысле, что никто точно не знает, какое поведение правильно), чтобы не сломать что-то. Т.е. опять-таки, всё идёт к тому, что нужно писать тесты, документирующие поведение системы (BDD), нужно уделять особое внимание бизнес-логике, модели (DDD). Я на своём опыте понимаю, что это не просто красивые слова, хотя вот относительно недавно (года 2 назад?), очень скептически относился к тому же BDD. Это становится понятно после боли в заднице от legacy кода.

Собственно, основной мой пойнт в том, что я не вижу проблемы писать больше, если это снижает риски. Написание кода — это вещь, на которую уходит меньшая часть времени в любом случае.
 
Последнее редактирование:

AmdY

Пью пиво
Команда форума
Мой опыт подсказывает, что чем проще сделана система, тем проще её модифицировать и поддерживать. Гибкость нужно закладывать через рефакторинг, когда это реально понадобилось, а не сидеть и медитировать заранее. YAGNI

Все бест практики очень нужны только когда ты разработываешь систему, ядро которой в последствии нельзя апдейтить. Хотя, вордпресы и без этого неплохо поживают, вот вам и говнокод на практике, а не в теории.
 

Вурдалак

Продвинутый новичок
А best practices как раз нужны для того, чтобы код был простой. Простой в каждом своём слое. Есть очень простой MysqlUserMapper. Есть очень простой класс User. С помощью декораторов я могу навешать любую логику для mapping'а: писать в 2 хранилища (Redis/MySQL) одновременно, реализовать шардинг и т.д. Всё интуитивно понятно:
Код:
AcmeCorp/
└── User
    ├── User.php
    └── UserRepository.php
Infrustructure/
└── Repositories
    └── User
        ├── DoctrineUserRepository.php
        ├── PinbedUserRepository.php
        └── RedisUserRepository.php
А что делать с Eloquent — я хз. Даже если допустить, что мы что-то подобное сделаем, у нас сама сущность будет грязной, с методами для базы данных. Типа грязный интерфейс: вроде бы доступно, а хз можно ли юзать.
 
Последнее редактирование:
Сверху