Когда лучше применять статические свойства, методы, классы? А когда их использовать не стоит?

Вакансии в Москве: Ведуший PHP разработчик 110-150к

Тема в разделе "Вопросы по теории программирования", создана пользователем zerolvl, 14 фев 2017.

  1. AmdY

    AmdY Пью пиво Команда форума

    Сообщения:
    6.822
    Ваш город:
    Belarus, Minsk
    Adress:
    Country:
    Location on map:
    Так в том и дело, что в посте http://phpclub.ru/talk/threads/Когд...а-их-использовать-не-стоит.82884/#post-752004 была ссылка именно на сервисный класс Time, который помимо стати методов ещё и финализирован. При этом автор пишет, теперь у нас отличный путь для инстанцирования, просто юзай статик вызов, но если ты DDD-шник, то просто поменяй название методов и твой код станет клёвым. Плевать что в реальном проекте будут локализации для времени и будет меняться разделитель, это уже твоя проблема как обернуть мой клевый объект, гавно обёрнутое в бумажку пахнет малиной.
     
  2. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Какой же это сервис, это обычный value object, посмотри внимательнее, а потом маши руками. Ты разве не в состоянии понять, что там static method используется чисто для выразительности? Он абсолютно никак технически не отличается от обычного new Time(). Или ты не понимаешь что такое «сервис»?
    Модель, которая нужна в расчётах, совершенно не обязана отвечать требованиям модели, предназначенной для вывода.

    Я теперь практически убеждён, что ты не троллишь, а ты просто деревянный. Годы тупого «херак-херак, пойду менять проект» дают о себе знать.
     
  3. AmdY

    AmdY Пью пиво Команда форума

    Сообщения:
    6.822
    Ваш город:
    Belarus, Minsk
    Adress:
    Country:
    Location on map:
    В том то и дело, что эти статические методы превращают VO в сервис, они парсят и рассчитывают данные и лишь потом создают VO. Фактически эту логику вообще нужно выносить за пределы класса.

    Так строка со временем принимает на ВХОД и парсится внутри по определённым параметрам, которые жёстко описаны ВНУТРИ. Какой вывод?

    Скорее наоборот, я гибкий, т.к. пробую разные подходы и концепции, меня взгляды исходя из проекта и инструментария. Но я уверен, что статические методы вкупе с финализацией это ацкий гавнокод, который на порядок усложняет поддержку проекта. Я привёл примеры изменений на проекте к которым не готов этот кусок кода, без переписывания или декорирования. Хотя если цель стать незаменимым на проекте, то такой подход рулит.
     
  4. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Она не превращает в сервис, эта логика статична. По твоему мнению, я так полагаю, любая логика превращает объект в сервис? Зачем её нужно выносить, если она гармонично смотрится с самим объектом? Так сказать highly cohesive.

    Не имеет значения, вход или выход, это детали представления. У нас есть какой-то внутренний DSL, в котором мы имеем право выбрать удобный формат для описания бизнес-логики. Если же требуется, чтобы при взаимодействии с клиентом (данные нам от него или от нас ему — не суть) мы использовали другой формат — без проблем, сконвертируй, отформатируй как тебе нужно. По той же самой причине мы не экранируем HTML перед записью в БД: HTML-экранирование — это деталь конкретного формата, пусть там и остаётся, нам на это пофиг.

    Классический пример VO — это DateTime. Но без учёта системных часов, нужно представить, что мы не используем «now». Там много логики и она достаточно сложная, но она статична и григорианский календарь он и в Африке григорианский. DateTime можно создавать разными способами: через timestamp, через явное указание даты или даты/времени и т.д.
    В Java 8, например, учли ошибки прошлого и сделали очень приятный immutable API для работы с датой/временем: http://www.oracle.com/technetwork/articles/java/jf14-date-time-2125367.html
    Там куча различных способов получения объекта:
    — это и есть статические конструкторы, о которых мы говорим.

    Какой-то религией попахивает, давай факты. А чем плох final в данном случае?

    По-моему, я от тебя не видел ещё ни одного примера. Когда это ты успел их привести? Я тебя спрашивал, но ты тупо игнорил мои вопросы, потому что тебе не нужно разбираться в проблеме, у тебя уже есть религия, тебе больше ничего не нужно.
     
    Последнее редактирование: 17 фев 2017 в 16:35
  5. AmdY

    AmdY Пью пиво Команда форума

    Сообщения:
    6.822
    Ваш город:
    Belarus, Minsk
    Adress:
    Country:
    Location on map:
    Так если есть DSL и это трансформируется выше, зачем тогда ещё раз разбирать этот DSL в Time::fromString или Time::fromTime? А если класс использовать вне DSL, то надо лазить в код, чтобы смотреть этот формат?
    Ты сам привёл ссылку в посте к которому был мой комментарий http://verraes.net/2014/06/named-constructors-in-php/

    Так системные часы это очень важный нюанс, в не знаю как в Java, но в php ещё и таймзоны берутся из php. А они периодически меняются и DateTime начинает работать не корректно, потому ни в коем случае не стоит использовать статик вызовы напрямую. Это реальный мир, а не теория.
     
  6. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Я эту фразу понимаю так, что ты оставлял комментарий в Disqus по ссылке. Но там единственное русскоязычное имя — Leonid Mamchenkov, комментарий оставлен 3 года назад. Или я пропустил его там где-то? Или ты имел в виду что-то другое? В рамках этой темы я от тебя примеров не видел, ты лишь голословно заявлял, что будут проблемы, что «финализирование» — это грех и всё в таком духе. И ни одной строчки кода.

    Ты говоришь, что если в DateTime есть, грубо говоря, метод-синглтон, то статические методы использовать нельзя. Если сосед-Вася — алкоголик, то с Васями дружить нельзя — они алкоголики. Где логика? Нет, это лишь обозначает, что не нужно использовать конкретно этот метод-синглтон. Получение текущего системного времени тут — это исторически сложившийся хак. Там, где ты не хочешь зависимости от системного времени — не используй DateTime::now().

    DateTime::now() — это всего лишь неявный SystemClock::getInstance()->getNow(): DateTime. А это, внимание, неявная статическая переменная DateTime::$systemClock. Возвращаемся к тому, с чего начали: проблема в static-переменных, а не в static method'ах как таковых.
     
  7. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Если говорить другими словами, то у нас несколько конструкторов, каждому из которых мы дали какое-то имя. Ты выступаешь против этого, потому что как-то раз ты купил кроссовки, а тебе были не по размеру и с тех пор ты ходишь только в туфлях, потому что от кроссовок у тебя остался осадочек. Если капнуть глубже, то выходит, что ты против нескольких конструкторов в принципе. Так что говори прямым текстом: тебе не нравится перегрузка конструкторов. Причем тут static-то?
     
  8. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    Ну - за пятницу!

    Нарушить SRP всегда проще. @TODO не забудь в коде оставить для будущих поколений.
     
  9. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    В DateTime не может быть переменной $systemClock потому что значение приходит от системного вызова. DateTime - это именно сервис, драйвер.
    Статическая переменная - локаль, она на уровне операционной системы, и для PHP это внешний сервис.
     
  10. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Нет, в DateTime есть фабрика-сервис, а сам DateTime таковым не является.
     
  11. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    Такой же драйвер, как PDOStatement - получает внешние данные, и предоставляет API для работы с ними в php.
    Но мы не пишем PDOStatement::fetch('current_statement');
    Очевидно, что вместо массива можно внезапно получить объект.
     
    Последнее редактирование: 17 фев 2017 в 21:43
  12. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Я не вполне понимаю о чём ты, но ты продолжай, мне интересно.
     
  13. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    О том, что если с Васей-алкоголиком проблемы, то и с Петей-алкоголиком можно ждать того же.

    Твое утверждение, что в DateTime внутри статическая переменная - неверно. Состояние у внешнего сервиса, приложение не должно полагаться на его неизменность.
     
  14. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    Она есть неявно: это сервис «системные часы».
     
  15. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    @AmdY писал про локаль - это неявная переменная. Сервис "системные часы" - это сервис, а не переменная, это источник данных.
     
  16. fixxxer

    fixxxer К.О.

    Сообщения:
    11.711
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on map:
    @grigori, я потому и обобщил про наличие состояния
     
  17. Вурдалак

    Вурдалак Newbie

    Сообщения:
    5.651
    Ваш город:
    Russia, Moscow
    Adress:
    Country:
    Location on map:
    По-моему, ты как обычно встрял с комментариями, которые не имеют отношения к дискуссии.
     
  18. grigori

    grigori Moderator Команда форума

    Сообщения:
    6.431
    Ваш город:
    Stormwind
    Не только у класса, а у любого компонента, включая источник и инфраструктуру ( os, файловая система) - все, чье состояние влияет на данные. У класса состояния может и не быть.

    Это приводит нас к любым внешним и внутренним данным, кроме данных в непубличных полях.
     
    Последнее редактирование: 18 фев 2017 в 00:14
  19. fixxxer

    fixxxer К.О.

    Сообщения:
    11.711
    Ваш город:
    Moscow, Russia
    Adress:
    Moscow, Russia
    Country:
    Location on map:
    Ну да, сайд-эффекты сюда же, какая разница-то. Вот в статических методах такого и стоит избегать.
     
  20. AmdY

    AmdY Пью пиво Команда форума

    Сообщения:
    6.822
    Ваш город:
    Belarus, Minsk
    Adress:
    Country:
    Location on map:
    Вот ты каждый раз впадаешь в гадания о том, что я думаю, хотя конкретно написал в первом же посте - я против статик конструкторов, так как они хардкодят зависимости в проектах. вместо foo(Contact\User $user) будут использовать User::register(); При этом всё держится на архитектурной самоуверенности, что это настолько простой объект, что его никогда не придётся менять. Хотя в том же DateTime как минимум 2 зависимости от системы - системное время и таблицы с таймзонами. Да иногда даже чёртов integer приходится заменять, так как числа слишком большие. Не понимаю зачем делать статичный фабричный метод, когда его можно вынести отдельно и дать нормально расширять. Тогда никаких проблем с поддержкой не будет, а так понятно откуда берутся такие опасения о данном скучном этапе.