Size: a a a

2020 September 05

SK

Sergey Kapralov in JUG NN
Romian Makhline
в этом то и проблема - тебе нужна цель, но ты сам назвал проблему, ее сложно выделить и цель таки может измениться, если ты ошибся. цена ошибки крайне высока в таком случае. поэтому наш код не модель реальности, а набор операций над данными, поэтому нам не важны цели, нам важны данные и операции, а их легко определить
Закрывая глаза на цель, ошибки не избежать. Если нет цели, врядли получится поддерживать стабильность абстракций — сервисы будут расти, обрастать зависимостями, их придется рефакторить, за счет зависимостей не всегда этот рефакторинг будет легким. Их муторно покрывать тестами, в тестах будет избыточное моккирование, которое будет вести к всяким регрессиям и фолс позитивам. В командной разработке это ведет зачастую еще к сложноразрешимым мерж конфликтам.
источник

RM

Romian Makhline in JUG NN
наша цель всегда одна и та же - получить данные, изменить, вернуть. по факту весь наш код это y = f(x) и мы рождаем эту f. попытки дать какие то иные цели - на мой взгляд пустая затея. для меня, как разработчика, важно только максимально эффективно сделать эту f. абстракции всегда будут подвижны, так как меняются данные, а абстракции всего лишь контейнеры, оболочки над данными(это даже из книги следуюет. для этого все эти интерфейсы и нужны)
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
но мне откровенно претит концепция объектов, я их воспринимаю только как структуры данных и не больше. и всегда делаю именно структуры данных
ИМХО такое прокатит разве что в скале, хаскеле или еще каком языке, где ФП развит на должном уровне. Такие языки как правило имеют в разы более развитые средства полиморфизма. В джаве, завязывая сервис на структурку, идет каплинг в разы жесче, чем в ФП, где для этой структурки ты можешь имплементировать тайпкласс и дальше работать через него.
источник

RM

Romian Makhline in JUG NN
не понял - на скале написал три с половиной функции и надоело чот. поэтому не помню что там тайпкласс.
допустим сервис A оперирует неким набором данным сокрытым в объекте B, тогда операции сервиса A явно принимают B, его предка или наследника в качестве аргумента. это довольно простая и очень легкодоступная схема не заставляющая жонглировать абстракциями
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
наша цель всегда одна и та же - получить данные, изменить, вернуть. по факту весь наш код это y = f(x) и мы рождаем эту f. попытки дать какие то иные цели - на мой взгляд пустая затея. для меня, как разработчика, важно только максимально эффективно сделать эту f. абстракции всегда будут подвижны, так как меняются данные, а абстракции всего лишь контейнеры, оболочки над данными(это даже из книги следуюет. для этого все эти интерфейсы и нужны)
Здесь надо разобраться с терминологией. Ты гришь — абстракции всегда будут подвижны из-за того что меняются данные. В моем понимании — данные это в 90% случаев не абстракция, а абстракция стабильна по определению. Абстракция — это высокоуровневая сущность, по максимуму отвязанная от деталей реализации. Конкретика — наоборот. Абстракция создается для реюза, конкретика — чтобы реюзть абстракции.
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
не понял - на скале написал три с половиной функции и надоело чот. поэтому не помню что там тайпкласс.
допустим сервис A оперирует неким набором данным сокрытым в объекте B, тогда операции сервиса A явно принимают B, его предка или наследника в качестве аргумента. это довольно простая и очень легкодоступная схема не заставляющая жонглировать абстракциями
Вопрос в том, что такое B. На практике это — чаще всего дтошка, идущая откуда нибудь с контроллера или базы. И это — проблема. Контракт контроллера и схема базы — по определению волатильные вещи. Именно поэтому сервис тоже будет волатильный, и не будет реюзабельной абстракцией.
источник

SK

Sergey Kapralov in JUG NN
Sergey Kapralov
Вопрос в том, что такое B. На практике это — чаще всего дтошка, идущая откуда нибудь с контроллера или базы. И это — проблема. Контракт контроллера и схема базы — по определению волатильные вещи. Именно поэтому сервис тоже будет волатильный, и не будет реюзабельной абстракцией.
Кроме того, на практике очень часто бывает, что конкретный метод не нуждается во всей структуре, но в отдельных ее частях (например, для проверки авторизации юзера не нужно знать его имя и фамилию, достаточно знать его роли). Но при этом зависит на всю структуру. Это ведет к тому, что без этой структуры, но в похожем сценарии сервис зареюзать уже не так просто. Тесты тяжелее писать, надо симулировать весь B. С изменениями на B регрессирует и тест, без веской на то причины. Тяжелее следить за тем, чтобы методы не разрастались, так как с B появляется собласн обработать в одном методе что нибудь еще.
источник

RM

Romian Makhline in JUG NN
когда не нуждается мы всегда можем выделить еще одну дтошку, например, если мы испытываем опасения. но вообще, если серьезно - сервис меняется реже, чем содержимое этой дто и нам важно что бы эти изменения влияли на сервис. как не странно, на моем проекте не используется спринг и вообще нету DI, поэтому мы все через new, считай как по книжке(по крайней мере по первой части), необходмиость переиспользовать сервисы сильно переоценена. чаще всего у тебя много моносервисов(у которых нет аналогов) и парочка сервисов реализации которых действительно могут быть разными но и тут чаще ты можешь это узнать еще на этапе инициализации приложения и нет фактичских проблем подсунуть то, что тебе нужно в очередной раз расширив интерфейс
источник

RM

Romian Makhline in JUG NN
я тут на своем опыте опираюсь и не претендую. чаще сервисы не переисользуются в моей практике, переиспользуются алгоритмы, которые используют сервисы. но это совсем другая тема)
источник

RM

Romian Makhline in JUG NN
в контексте моего проекта это менеджеры, или дуеры. чуваки которые умеют что то делать реальное и осязаемое
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
когда не нуждается мы всегда можем выделить еще одну дтошку, например, если мы испытываем опасения. но вообще, если серьезно - сервис меняется реже, чем содержимое этой дто и нам важно что бы эти изменения влияли на сервис. как не странно, на моем проекте не используется спринг и вообще нету DI, поэтому мы все через new, считай как по книжке(по крайней мере по первой части), необходмиость переиспользовать сервисы сильно переоценена. чаще всего у тебя много моносервисов(у которых нет аналогов) и парочка сервисов реализации которых действительно могут быть разными но и тут чаще ты можешь это узнать еще на этапе инициализации приложения и нет фактичских проблем подсунуть то, что тебе нужно в очередной раз расширив интерфейс
> сервис меняется реже, чем содержимое этой дто

Я б не был так уверен. Может мне так не везло, но в моем случае они меняются каждый день.

> необходмиость переиспользовать сервисы сильно переоценена.

Мне кажется это все просто потому, что человечество не видело альтернативы. Или находят альтернативу в ФП и грезят им, не без причин. Сервисы переиспользовать сложно, поэтому их и не переиспользуют.

> и нет фактичских проблем подсунуть то, что тебе нужно в очередной раз расширив интерфейс

Нет проблем с точки зрения сервиса. Но могут быть проблемы с точки зрения клиентов этого сервиса. Из того что я наблюдал — росло количество точек инжекций, усложнялись тесты. И я еще не говорю о том, что с каждым новым методом сервис растет в размерах.
источник

RM

Romian Makhline in JUG NN
да и пусть себе растёт - это группирует функциональность, а не размазывает ее ровным слоем по тысячи мелких файликов. чем хорош интернет - там можно найти все, а чем плох? придется поискать. вот это проблема мелких классов даже с хорошим именованием. опять же по опыту - даже если есть гайдлайны как все именовать зачастую поиск нужного кусочка кода превращается в долгое исследование бизнес кейсов и глупых тестов.
у сервиса клиентами выступают вещи высшего порядка - сущности оперирующие сервисом как набором операций над имеющимися у них данными. у них не могут возникать проблем с ростом сервиса просто в силу того что они и являются инициатором этого роста.

если человечество за те 30 лет существования джавы не увидело "лучшего" пути, вероятней всего путь не самый лучший
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
я тут на своем опыте опираюсь и не претендую. чаще сервисы не переисользуются в моей практике, переиспользуются алгоритмы, которые используют сервисы. но это совсем другая тема)
Я допускаю что у нас расхождения в терминологии, особенно с учетом того что у тебя нет DI. Алгоритмы чаще всего являются приемлемыми абстракциями.
источник

RM

Romian Makhline in JUG NN
на этом проекте нет DI, на предыдущем был, и все же сервисы редко переиспользовались. ну или я этого просто не заметил.
источник

RM

Romian Makhline in JUG NN
сервис умеет дергать кого нужно с нужными настройками
источник

RM

Romian Makhline in JUG NN
весь этот подход требует "сначала думай, потом делай" - это слишком рисковано
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
на этом проекте нет DI, на предыдущем был, и все же сервисы редко переиспользовались. ну или я этого просто не заметил.
Ну гляди, как я выше сказал. Есть юниты для реюза, есть юниты, которые реюзают. В твоем случае сервисы видимо входили во вторую группу. Что терпимо. На практике я такое никогда не наблюдал.
источник

RM

Romian Makhline in JUG NN
но если твой код не выполняет алгоритма над данными - то он лишь прослойка между базой и UI и в общем то не важно как сделан
источник

SK

Sergey Kapralov in JUG NN
Romian Makhline
весь этот подход требует "сначала думай, потом делай" - это слишком рисковано
Я это вижу иначе. Сколько ни думай, по закону мерфи впорешься. Но в моем случае это можно обнаружить буквально моментально. Достаточно ответить себе на вопрос — вот заказчик с новым требованием пришел — оно импактит хоть один интерфейс? Компрометирует хоть одну из целей? Импактит? Окей, значит нужен рефакторинг, цена его будет определяться количеством имплементаций и клиентов от этого интерфейса. И обьяснить его будет проще, мол "брателло, изначально предполагалась бизнес-цель А, а вот это требование в эту цель не вписывается. Мы все допустили ошибку, давайте рефакторить, ретроспективить, делать выводы как такого больше не повторить". Не будет такого, что ты начал делать, обнаружил импакт на один сервис, следом импакт на другой сервис, а вот тут еще тесты посыпались, а вот тут Вася интересную конструкцию из паттернов написал — она поехала...
источник

RM

Romian Makhline in JUG NN
хорошо спроектированная система, как ты предлаегаешь, даже если она будет спроектирована по каким то иным принципам при этом удовлетворяющим целям всегда будет давать такой ответ за ограниченное время. проблема в том, что это просто не возможно. ты предлагеашь подход с проектированием на перед всего до мелочей(через интерфейсы и соответственно контракты) это не только "надо подумать" это надо еще сделать и что бы оно работало быстро и что бы... в общем этого что бы много бывает. особенно начнутся проблемы над компксными данными, вдля которых сложно выделить хорошие абстракции. собственно абстракции и то, что они прямо завязаны на мышление разработчика это самое слабое место этой теории. твое и мое виденьего одного и того же объекта сильно разняться, мы оба выделим в какой то момент разные абстракции, они обе будут для нас хороши, но ужасны для другого. мне сложно привести сейчас какой то простой пример, но уверен, что он существует. мы как минимум можем допустить его существование и тогда стройная взаимозаменяемая система с использованием всех благородных принципев резко оказывается довольно сложно управляемой машиной. начинают течь абстракции в том смысле что происходит логический взрыв роста, это не избежно я бы даже сказал основываясь на том, что с течением времени любая программа которая претендует на моделирование действительности сталкивается с тем, что реальность слишком сложна, для упоковывания в байтики на диске на данный момент. это в свою очередь приводит к двойной работе - пока я рефакторю то, что наколякал Вася(я на самом деле врят ли буду рефактироить а как нибудь поверх впилю), ты в свою очередь будешь выделять абстракции.
что то, что это на мой взгляд одно и тоже, толкьо ментальных сил ты потратил больше, а я меньше
источник