Pull to refresh
35
0
Илья Сазонов @poxvuibr

Software developer

Send message
Подобно тому, как заряд аккумулятора не зависит от марки автомобиля, в котором он установлен, проблемы одной и той же DE одной и той же версии на разных дистрибутивах к проблемам дистрибутива отношения не имеют.

Проблемы одной и той же DE одной и той же версии на разных дистрибутивах? Это вы сейчас зачем сказали? Вы же назвали буквоедом человека, который сказал, что гном это стандартная оболочка на убунте. При чём тут DE одной и той же версии на разных дистрибутивах? Откуда это взялось? )))


А вы, стало быть, защищаете то ли непингуемого и необучаемого, то ли демагога.

Из чего это следует? Серьёзно, я вообще не понял ))

Во-первых, раз уж взялись буквоедствовать, то делайте это правильно.

Я со стороны наблюдаю за дискуссией и со стороны видно, что буквоедствовать начали вы. Когда вы увидели слововсочетание "стандартная оболочка", которое комментатор использовал в переносном смысле и из контекста было понятно, что это за смысл, вы зачем-то стали понимать его буквально. Это в общем и есть буквоедство ))))

Задача для собеседования: как написать не пустой where, который ничего не делает.

where 1=1


Это имеется в виду?

Почему я должен инвестировать свое время именно в JPA?

Потому, что JPA сейчас практически везде. Куда бы вы не пришли, там с высокой вероятностью будет JPA.

JPA пытается создать иллюзию отсутствия базы данных, в частности спрятать от программиста необходимость отражения изменений в БД.

JPA не пытается. Это разработчики пытаются использовать JPA таким способом и мне кажется большинство экспертов прямо говорят не делать так.


JPA используется для того, чтобы вытащить данные из базы, поправить и скинуть обратно. Или, чтобы просто вытащить. Ещё JPA помогает программисту строить запросы. Ключевое тут помогает. Отдавать построение запросов на откуп JPA — нежелательно.


Конструктор по умолчанию
Классы должны быть открытыми для наследования

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


Объекты должны быть изменяемыми

Повторюсь, что Entity сделаны для того, чтобы выгрузить данные, поправить и скинуть обратно. Если у вас какой-то другой воркфлоу, то не используйте Entity, JPA в этом случае всё равно будет вполне себе полезной штукой.


Весь код становится кодом с побочными эффектами

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


С ленивой загрузкой надо быть постоянно начеку. Каждый раз, написав что-то в духе entity.getXXXs, задумываться — не случится ли здесь N+1 запрос.

Да, надо. Если обходиться без JPA — придётся писать запрос руками. Если с JPA — придётся руками добавить настройки, чтобы ленивой загрузки не было. Выбор индивидуален, но с JPA работы, наверное меньше. Особенно учитывая, что писать запросы руками JPA не мешает.


Я уверен, что этот список будет и дальше расти. Сейчас я выписал только то, что лежит на поверхности.

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


Получается, что теоретически JPA можно использовать, не жертвуя качеством дизайна и производительностью. Однако придётся пожертвовать идиоматичностью использования JPA.

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


По моему мнению, применение JPA уместно, когда важно сделать быстро, дёшево и плохо.

Если не знаешь, как пользоваться инструментом, всегда получится плохо. Но быстро и дёшево — далеко не всегда )).


Основной недостаток JPA в том, что разработчики не хотят его осваивать )).

Т.к. в Kotlin я для сущностей использую Data Class'ы.

А зачем? equals всё равно переопределять, hashCode всё равно переопределять, конструктор без параметров всё равно нужен


Аналогично с LazyInitializationException. Отказываемся от транзакционности

Мне кажется, лучше словить экспешн и поправить код. Дешевле выйдет. ))

Плюс ещё между памятью и регистрами несколько уровней кеша, чтение из которого тоже сильно быстрее, чем из RAM

— Когда фиксишь фидбек по ревью, то делаешь fixup конкретных коммитов, так, что история остается чистой, соответственно, rebase + force push в свою ветку

И ещё потом прогон юнит тестов для всех коммитов, на которые повлиял rebase?

А вот вам запрещённая цитата из этой самой статьи, про этот самый кусок кода. Эту цитату, почему-то, обычно не цитируют.


The improvement in speed from Example 2 to Example 2a is only about 12%, and many people would pronounce that insignificant.

The conventional wisdom shared by many of today's software engineers calls for ignoring efficiency in the small; but I believe this is simply an overreaction to the abuses they see being practiced by pennywise-and-pound-foolish programmers, who can't debug or maintain their "optimized" programs.

In established engineering disiplines a 12 % improvement, easily obtained, is never considered marginal; and I believe the same viewpoint should prevail in software engineering~ Of course I wouldn't bother making such optimizations on a oneshot job, but when it's a question of preparing quality programs, I don't want to restrict myself to tools that deny me such efficiencies

И примерный перевод:


Увеличение скорости в этом примере составляет где-то 12% и многие сочтут его незначительным. Общепринятое мнение, которго придерживаются многие разработчики призывает игнорировать эффективность в мелочах; но я считаю, что это просто чрезмерная реакция на злоупотребления которые допускают всякие разработчики, которые потом не способны поддерживать или отлаживать их "оптимизированные" программы.

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

Конечно, я не стал бы делать такие оптимизации в одноразовой задаче, но когда встаёт вопрос о подготовке качественных программ, я не хочу ограничивать себя инструментарием, который не даёт мне таких возможностей.

Живите с этим )))

Впрочем, непонятно, что это перетягивание Кнута на свою сторону даёт любому из оппонентов :)

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

Ну камон, это какое-то агрессивное передёргивание слов оппонента

Ну нет )). Это агрессивная попытка побудить оппонента прямо сказать, что он с цитатой из Кнута не согласен )).


вполне понятно же, что человек имел в виду

Вроде понятно. Но и позиция того же Кнута, она немного сложнее, чем многие думают. Цитата про 12 процентов, она, кажется на предыдущей странице по отношению к цитате про преджевременную оптимизацию.

Я написал ровно то, что написал.

Вы написали, что полностью согласны с Кнутом, а я процитировал Кнута. С этой цитатой вы, как я понимаю, тоже согласны.

В заголовок вынесен принцип, который очень опасно абсолютизировать, и да, я полностью согласен с Кнутом.

И с тем, что 12 процентное повышение производительности, легко получаемое, никогда не сочтут незначительным, тоже согласны?

Вот кстати аналогии с птицами тут могут не подойти, изначально крыльев и оперения ни у кого не было

Перья уже были у динозавров, крылья у некоторых из них тоже были и похоже, что некоторые из тех, что с крыльями, даже могли летать. У предков птиц уже было почти всё, что того, чтобы полететь. нужно было только немного подкрутить настройки.


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

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

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


Если нужна логика из CustomerService — нужно инджектить CustomerService. Если нужна логика из AdditionalService, нужно инджектить AdditionalService. Если нужна логика из обоих, то нужно инджектить оба.


Приём, описываемый в статье имеет, смысл только если все классы из проекта используют методы и из AdditionalService и из CustomerService. Даже в этой подозрительной ситуации я бы инджектил сервисы отдельно. В крайнем случае выделил бы обёртку для используемых во всех классах методов. Но мне представить такую ситуацию очень непросто.


Лично я выступаю за то, чтобы просто вообще запретить наследование в компонентах, чтобы ни у кого не возникло соблазна сделать что-то похожее на описанное в статье. В таких случая нужно использовать композицию. Как и 90% остальных случаев.

Мне кажется, это не аргумент.

Это распространённое мнение. Оно подкрепляется тем, что если не делать моков, то получается тестирование интеграции методов между собой, что скорее хорошо, чем плохо.


Если падает тест А и тест Б, причем известно что функция А вызывает Б, то чинится Б а потом смотрится, помогло ли это для А или нет.

Разработчику, который будет править тест придётся потратить время, чтобы понять кто там кого вызывает и какой тест надо чинить в первую очередь. Это и то, что одна правка разваливает много тестов, может даже повредить внедрению юнит тестирования на проекте.


А вот в этот момент как раз стоит сказать "такие разработчики нам не нужны".

Этот момент ещё нужно вовремя отсечь, что не так просто, как кажется. Легче запрещать чекстайлом всё и с запасом.


Скажите, вы в основном работаете в команде? И ещё интересно какого размера команда, если так.


В моей практике такя фигня начинается в любой команде, где больше пяти человек, если в проекте ведётся активная разработка.

Я пытаюсь понять ценность этого. То есть “надо замокать” — окей, я понял вашу позицию. Но я не понимаю зачем её мокать?

Я отвечу на ваши вопросы в обратном порядке, хорошо? Потому что так мне будет проще высказать свою мысль.


Чистую функцию нужно мокать, потому что в ней какая-то сложная логика и для того, чтобы понять, что надо подать на вход, чтобы получить требуемый выход, нужно серьёзно подумать. А подбирать надо будет так, чтобы всё это было удобно ещё и для тестирования внешней функции. Проще замокать внутреннюю функцию, чем думать. Это, конечно не аргумент, если функция простая.


Также, когда мы захотим эту функцию порефакторить, упадёт не только её тест, но и тесты кода, который её вызывает. Это не проблема, если разработчик постоянно запускает тесты, но по моим наблюдениям, разработчик долго правит код, а потом тесты падают уже на CI. И поди потом разбери, почему упали тесты.


Возможно вы скажете, что такие разработчики нам не нужны, но кто тогда будет работать? )))


И? Вот вы сделаете мок (псевдокод) capitalize.mock(“foo”, “Foo”).mock(“bar”, “Bar”)… Чем он лучше просто вызова capitalize?

Это непростой вопрос, поскольку метод capitalize очень очень простой. Если бы он был библиотечным, я бы даже не подумал его мокать.


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


Самая очевидная правка — сделать так, чтобы этот метод капсил не слово, а целое предложение. То есть переводить в капс только первую букву первого слова, а всё остальное до точки, вопросительного знака или восклицательного знака не трогать.


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


Дальше выяснится, что в capitalize могут передать и целый текст и хорошо бы учесть это в коде. И некоторые слова в тексте надо будет капсить, поэтому рядом с методом будет список таких слов.


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


Следующим шагом решат что слова для капса надо добавлять через админку. А значит в методе понадобится доступ к базе данных. Думаете, его перенесут в сервис? Нет, там просто вызовут Context.getBean и спокойно продолжат использовать его в статическом контексте. Потому что для этого не придётся делать правки по всему коду, а при переносе в сервис придётся.


Может быть вы думаете, что всё это страшилки, которые выдумали взрослые? Я тоже думал, пока мне лично не пришлось объяснять людям, что так делать нельзя. И вы знаете, не убедил! Делали через “ну так уж и быть, раз тебе так печёт, то ладно”.


Перефразируя известное изречение скажу, что каждый статический метод в большом проекте неконтролируемо растёт, пока не поучает возможность отсылать электронную почту

Хм. При чём тут мой бог? Ничего не понял.

Да всё просто )).


Вы там успокаивали окружающих, что в Джаву синтаксический сахар точно не проползёт.


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


Я со своей стороны утверждал, что Ломбок кроет новые языки в том смысле, что в нём запилят фичи, которые не запилят в языках. Не и ещё его можно использовать с восьмой Джавой, хотя там я этого не сказал.


А с появлением в плагине фичи, описанной в статье, Ломбок делает ещё один шаг к превращению Джавы во что-то, чем она раньше не была. То есть хотя синтаксический сахар не пролезет в стандарт, он всё-таки пролез в практику применения языка. Де факто то, про что вы говорили, что этого не может быть никогда — случилось )).


Вот это я имел в виду, когда использовал фигуру речи “где теперь ваш бог”.


Кроме того, я ведь обращался не только к вам. Другие люди рядом в комментариях говорили, что Ломбок он только сокращает геттеры и всё такое, а тут БАХ и вот.


Я, кстати, тоже участвовал в поддержке ломбоковских extension-методов в IntelliJ IDEA.

Тем самым добавляя в Джаву синтаксический сахар, который вам не нравится ))

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

Ваша позиция мне понятна, но я с вами категорически не согласен.


В своём примере я говорю про функцию, которая капитализирует не все слова, использующую функцию capitalize, которая капитализирует все.


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


Если у нас есть функция, использующая другие функции и эти внутренние функции чистые, то их всё равно полезно замокать. В том случае, если логика в них достаточно сложная.

Information

Rating
4,932-nd
Works in
Date of birth
Registered
Activity