я понял, наконец

grigori

( ͡° ͜ʖ ͡°)
Команда форума
почему смелости? всеобщее знание и опыт с JS помогло, а дизайн JS - случайность

набрасывает или нет, надо помнить для чего java создавалась - не для серверных приложений, а для клиентского UI на тонких клиентах :) как ни забавно это сейчас звучит
 

fixxxer

К.О.
Партнер клуба
Для меня забавно не звучит, я помню, откуда взялся jar, да и в МЦСТ все эти кофейники видел еще в начале нулевых.
Да и, скажем, у тебя в сим карте с большой вероятностью кастрированная java, например :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
в принципе, множественное наследование у нас есть и так в виде трейтов,
на первый взгляд неплохая идея убрать implements в php, оставить duck typing, но такую проверку в runtime реализовать могут только два человека
 

whirlwind

TDD infected, paranoid
Опять вы про абстрактные классы. Контракт - это любые публичные члены любого класса. Наружу торчат сигнатуры вызовов - это и есть контракт, соглашение или интерфейс класса. Для примера откройте MSVC и посмотрите на code explorer. В контекстных менюшках есть go to declaration и go to definition. Вот declaration - это и есть контракт. Любым способом: интерфейсом, абстрактным классом, обычным классом - просто список мемберов с прототипами и типами. Снаружи код мембера не виден. Если вы в редакторе видите код паблик мембера, это не значит что его сигнатура перестает быть частью контракта. Интерфейс - это просто языковая форма декларативного объявления контракта. Если абстрактный класс содержит паблик мемберы, прототипы (прототип метода = сигнатура вызова) этих мемберов становятся частью контракта. Если у абстрактного класса защищенные мемберы, это DI путем наследования (например, фабричный метод). Любой публичный метод в конечном классе есть часть контракта. Это первично. А интерфейсы и абстрактные классы это сверху навешано.
 
Последнее редактирование:

grigori

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

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

Вслед за @fixxxer прихожу к выводу, что в userland декларации контрактов лучше писать не "interface", а абстрактными классами без защищенных и приватных членов. Такой контракт можно будет переименовать в интерфейс в несколько кликов, но сходу не могу придумать кейс.

Если я пишу общий код, и хочу позволить другим разработчикам в их классе реализовать множество контрактов, не только со мной - интерфейсы полезны как тип параметра функции. Однако, придется страдать без публичных свойств. Я использую слово "страдать" потому что скорость доступа к данным при итерации по десяти тысячам строк становится важной, вызывать геттер 10 тысяч раз иногда недопустимо, как-то я в это уперся.
А можно и трейтами обойтись, как ядро symfony.
 

fixxxer

К.О.
Партнер клуба
А смысл свойствам быть частью абстрагированных контрактов? Всегда, когда они нужны, у нас совершенно конкретный пользовательский тип.
Public readonly свойство уместен только для value objects/DTO, для которых никакое абстрагирование не требуется по определению - это даже не полноценный объект, просто immutable structure с конструктором. Просто кастомный тип данных, ты же не пытаешься абстрагировать string или integer.
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
Если у абстрактного класса защищенные мемберы, это DI путем наследования (например, фабричный метод).
Вот это неоднозначное утверждение, тут надо уточнить, как именно фабричный метод используется.

А в остальном согласен, я бы и не стал про абстрактные классы рассуждать, если бы вопрос так не стоял
 

AnrDaemon

Продвинутый новичок
Если геттер-сеттеры сделают частью языка по принципу того же ObjectPascal, проперти придётся тащить в контракт.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
А смысл свойствам быть частью абстрагированных контрактов?
Отложи ЧСВ. В 95% кода в мире публичные свойства - часть интерфейса.

Всегда, когда они нужны, у нас совершенно конкретный пользовательский тип.
Если каждый DTO был конкретным пользовательским и отличался от других, не были бы нужны generic-и.
В реальности у нас есть коллекции типа DateTime, Imagick, и полный packagist библиотечных объектов и с публичными полями, и с методами.

Public readonly свойство уместен только для value objects/DTO, для которых никакое абстрагирование не требуется по определению - это даже не полноценный объект, просто immutable structure с конструктором. Просто кастомный тип данных, ты же не пытаешься абстрагировать string или integer.
DTO - это объект. Тезис о том, что DTO - не полноценный объект, любопытно, но это причуда. Есть объекты, есть массивы. Неполноценные объекты - это лямбда, анонимный класс и трейт.
 

Adelf

Administrator
Команда форума
DTO - это объект. Фантазия о том, что DTO - не полноценный объект, любопытно, но это лишь твои личная причуда.
DTO - это плюс-минус просто параметры для метода. И относиться надо к ним так же.
 
Последнее редактирование:

grigori

( ͡° ͜ʖ ͡°)
Команда форума
@Adelf было бы хорошо привести не только личное мнение вас четверых.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Попробую привести простой контраргумент.
Если VO - не объект, а структура, вы пишите процедурный код. Ваши модели - функции, обернутые в автолоад, а VO - структуры, и вы просто пишите на PHP как на С.

ООП - это в первую очередь полиморфизм. Считая VO простой структурой, вы отказываетесь от полиморфизма, следовательно - от всей идеи ООП.
Это не плохо, это просто другое.

В ООП VO - это в первую очередь контракт. Методы count, toArray, toJson, toCSV, преобразование кодировок данных достаточно распространено в элементах коллекций.

По вашей логике выходит, что все авторы всех библиотек php все делают неправильно, смешивают данные времени c методами расчетов времени, и одни вы владеете истинным знанием.
 
Последнее редактирование:

Adelf

Administrator
Команда форума
Конкретно эти объекты низвергнуты в касту "просто передатчиков данных". Но это не значит, что все объекты такие же.
 

Adelf

Administrator
Команда форума
В ООП VO - это в первую очередь контракт. Методы count, toArray, toJson, toCSV, преобразование кодировок данных достаточно распространено в элементах коллекций.
А коллекция не может быть параметром функции?
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
отлично может, и это полноценный объект со своими методами
 

Adelf

Administrator
Команда форума
Ладно. Попробую серьезно писать :) Кстати, конкретно здесь мы друг другу не противоречим, поскольку я лишь сказал что дтошка представляет собой список параметров функции. Соответственно и коллекцию твою она может содержать.
Но если пойти глубже, то ты хочешь полноценное ООП в полях DTO. Полиморфизмы и инкапсуляции. Проблема тут такая, что изначально ДТО создали для того чтобы ими кидаться по сети. Между сервисами. Слово Transfer как раз на это намекает. Для этого они должны уметь полностью сериализоваться и десериализоваться. и если в пхп мы легко можем это делать с почти любыми объектами, то в других языках это весьма непросто для объектов, которые прячут свою структуру. Именно поэтому не принято в дтошках сильно всё усложнять.
 
Сверху