Недавно сделал рефакторинг, который выглядит дико даже для меня, но в итоге, подумав, вполне нормальный.
Был класс, который размещал два компонента в окошке. Обычно это label и поле к нему. Но иногда там был только label и тогда field было null. И наоборот могло быть тоже. В итоге была огромная конструкция где проверялись все возможные варианты - кто null, кто не null. А когда добавились еще параметров стало просто невмоготу.
Что я сделал? Вместо одного класса FieldPair, в котором оба поля могли быть null, я сделал три. OnlyLabel, OnlyField and FieldPair. И в каждом только ненулевые компоненты. И все стало так сильно проще! Я даже мелкий баг нашел сразу же.
Был класс, который размещал два компонента в окошке. Обычно это label и поле к нему. Но иногда там был только label и тогда field было null. И наоборот могло быть тоже. В итоге была огромная конструкция где проверялись все возможные варианты - кто null, кто не null. А когда добавились еще параметров стало просто невмоготу.
Что я сделал? Вместо одного класса FieldPair, в котором оба поля могли быть null, я сделал три. OnlyLabel, OnlyField and FieldPair. И в каждом только ненулевые компоненты. И все стало так сильно проще! Я даже мелкий баг нашел сразу же.
❤13🔥8👍4
https://gist.github.com/adelf/bf9e8d6d094e5c01c24689e4c92ce9c5
Простой пример реального Value Object на Котлин(из кода Laravel Idea). Скрывает свое содержание. При сравнении не учитывает регистр. Ну и еще пару фич в нем. Раньше все в строке хранил в формате "схема.таблица", но стало сложно управляться. Теперь намного проще.
Благодаря equals&hashCode, Java/Kotlin умеет их использовать в качестве ключей массива(Map) и таблички в разных регистрах спокойно работают. Удобно.
Простой пример реального Value Object на Котлин(из кода Laravel Idea). Скрывает свое содержание. При сравнении не учитывает регистр. Ну и еще пару фич в нем. Раньше все в строке хранил в формате "схема.таблица", но стало сложно управляться. Теперь намного проще.
Благодаря equals&hashCode, Java/Kotlin умеет их использовать в качестве ключей массива(Map) и таблички в разных регистрах спокойно работают. Удобно.
Gist
DatabaseTableName Value Object
DatabaseTableName Value Object. GitHub Gist: instantly share code, notes, and snippets.
👍11
Сегодня приснился кошмар. Я попал на работу в крутую компанию. Начал писать какой-то функционал и написал тест. Менеджер начал мне обьяснять как добавить этот тест в их систему. Надо взять бланк, описать название теста, на каких кейсах его запускать. Потом понести этот бланк на другой этаж к админам! Получить от них одобрение, инвентарный номер теста(!!!), поставить подписи и все! Менеджер всю дорогу хвастался насколько удобен этот процесс)
Я сидел там у админов и не верил в происходящее. Номер мой тест получил 347. А система огромная! Значит тестов почти не пишут. Понятно почему)
Мимо проходил знакомый, мы поздоровались и я сказал "Вот коллегой твоим стал, но видимо ненадолго"
Я сидел там у админов и не верил в происходящее. Номер мой тест получил 347. А система огромная! Значит тестов почти не пишут. Понятно почему)
Мимо проходил знакомый, мы поздоровались и я сказал "Вот коллегой твоим стал, но видимо ненадолго"
😁37🤣18🔥4👍1
О трудностях разработки плагинов. Я начинаю поддержку новой мажорной версии шторма сразу как только выходит EAP. Соответственно ориентируюсь на ранние релизы. Но где-то между 2023.1 и 2023.1.5 они переместили классы в другой неймспейс) Это нормально сделать между мажорными версиями, поскольку эти классы помечены как экспериментальные, и что они могут меняться. Но не между минорными же! Такое очень сложно поддерживать...
Здесь пришлось просто не использовать эти классы. Отложить их до 2023.2 и надеяться, что такого не случится еще разок
Здесь пришлось просто не использовать эти классы. Отложить их до 2023.2 и надеяться, что такого не случится еще разок
👍18😱4😢3
class FractalTransformerGenerationTest: BaseAppModuleSystemTestCase() {
init {
addPackageDependency<FractalPackage>()
addDependency(EloquentModelsDependency())
}
У меня сильно разрослись тесты и понадобились некоторые бест-практис, чтобы навести порядок. Тестам часто нужна какая-то инициализация. Она выполняется в setUp/tearDown. Если тестов с общей инициализацией много - то убирают дублирование путем выделения базового класса и вынесения этой инициализации туда.
До определенного момента я так и делал, а потом понял, что иногда нужны разные инициализации. Вот здесь мне нужно подключить определенный пакет(Fractal) и некоторые Eloquent модели к проекту. Плюс там BaseAppModuleSystemTestCase тоже не просто так стоит)
Пора применять композицию вместо наследования. Сделал простой интерфейс
interface TestDependency {
fun setUp(fixture: CodeInsightTestFixture)
fun tearDown(fixture: CodeInsightTestFixture) {}
}
ну а в самом базовом тестовом классе:
private val dependencies =
mutableListOf<TestDependency>()
fun addDependency(dependency: TestDependency) = dependencies.add(dependency)
override fun setUp() {
super.setUp()
...
dependencies.
forEach { it.setUp(myFixture)
}}
override fun tearDown() {
dependencies.
forEach { it.tearDown(myFixture)
}super.tearDown()
}
Очень удобно стало. Намного меньше мусора теперь в тестах. По хорошему надо и этот BaseAppModuleSystemTestCase превратить в тестовую зависимость, но пока лень.
👍5😱1
В PHP-коммунити новый холивар. Пакет Unfinalize, который проходится по всем классам библиотек в vendor и убирает ключевое слово final из всех классов и методов. Разумеется, пакет получил большую поддержку и кучу благодарностей.
Испанский стыд - это самое точное описание того, что чувствую.
Испанский стыд - это самое точное описание того, что чувствую.
😁49👍6😱3🤯1😐1
fun getSpatieToolPackageName(methodReference: MethodReference): String? {
return getNameMethodCall(methodReference)
?.getParameter(0)
?.getStaticStringValue()
?.removePrefix("laravel-")
}
Все чаще и чаще пишу в таком вот, функциональном стиле. Кратко, красиво, и комменты не нужны. Умная IDE типы возвращаемые серым справа показывает...
Для этого, правда, нужно, чтобы язык умел к любому чужому классу или интерфейсу написать метод. Kotlin и C# это умеют. Просто пишешь чтото вроде
fun String.removePrefix(s: String) { return this.что-то там... }
и работает.
🔥6👍4
Когда внезапно осознаешь, что твое приложение - многопоточное.
Прилетает в sentry такой эксепшен:
Я просто вызываю add() в стандартнейшем классе для списков и получаю странную ошибку. Но крайне редкую. Для тысяч юзеров всего 2 за неделю. В многопотоковом программинге я ноль, но это оно самое. Два потока одновременно пишут в один список и получают ошибку. Вчера еще более странную ошибку находил, с той же самой причиной.
Если данные приватные и пишутся под строгим контролем одного класса, чинить это несложно. Простые конструкции synchronized и все должно быть ок. Также, есть специальные thread-safe структуры данных(ConcurrentHashmap, ConcurrentList). Но внутри у них либо тот же syncronized, либо еще хуже, так что для меня проще так.
Прилетает в sentry такой эксепшен:
java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 0
at java.util.ArrayList.add(ArrayList.java:455)
at java.util.ArrayList.add(ArrayList.java:467)
at com.laravel_idea.plugin.translation.fetching.b.b.a(b.java:24)
Я просто вызываю add() в стандартнейшем классе для списков и получаю странную ошибку. Но крайне редкую. Для тысяч юзеров всего 2 за неделю. В многопотоковом программинге я ноль, но это оно самое. Два потока одновременно пишут в один список и получают ошибку. Вчера еще более странную ошибку находил, с той же самой причиной.
java.lang.ClassCastException: class java.util.HashMap$Node cannot be cast to class java.util.HashMap$TreeNode (java.util.HashMap$Node and java.util.HashMap$TreeNode are in module java.base of loader 'bootstrap')
at java.util.HashMap$TreeNode.moveRootToFront(HashMap.java:1986)
at java.util.HashMap$TreeNode.treeify(HashMap.java:2102)
at java.util.HashMap.treeifyBin(HashMap.java:770)
at java.util.HashMap.putVal(HashMap.java:642)
at java.util.HashMap.put(HashMap.java:610)
at com.laravel_idea.plugin.translation.fetching.b.b.a(b.java:16)
Если данные приватные и пишутся под строгим контролем одного класса, чинить это несложно. Простые конструкции synchronized и все должно быть ок. Также, есть специальные thread-safe структуры данных(ConcurrentHashmap, ConcurrentList). Но внутри у них либо тот же syncronized, либо еще хуже, так что для меня проще так.
synchronized(this) {
vendorData.add(data)
}
🔥9🤔6❤2👍1
Когда-то давно одним из основных продуктов JetBrains был Resharper. Умный плагин для C# разработки в Visual Studio от Microsoft. Долгое время спустя, убедившись, что они умеют делать собственные успешные IDE для кучи ЯП, они решили сделать Rider - среду программирования для C# (или всех .NET языков, тут не знаю). Но была проблема: тот умный решарпер, который понимал C# и на основе которого планировалось делать Rider, был написан на C#.
Решили это таким образом: появился некий бекэнд(решарпер), который понимает код, генерит подсказки и подсвечивает ошибки, и фронтэнд - сама оболочка, UI. Общаются они по внутреннему протоколу. JB ходили на конфы и рассказывали как сложно им оптимизировать это, чтобы работало с приемлемой скоростью, но с годами проблемы были решены, и насколько мне известно Rider потихоньку отвоевывает рынок у Visual Studio, хотя цифр конкретных у меня нет.
Архитектура Rider вынужденно повторила архитектуру современных SPA веб-приложений. И вроде бы получился некий уродец с кучей проблем. Тут и перформанс, и плагин нормальный написать - тоже надо и фронтэнд часть и бэкэнд. Но кто-то в JB решил, что это не баг, а фича!
И появился Fleet - "Next-generation IDE by JetBrains". Архитектура точно такая же - интерфейс это фронтэнд, а вся умнота(там это называется Smart mode) - бекэнд. А фича в том, что бэк можно разместить как на компе юзера(и тогда получим более-менее обычную JetBrains IDE), а можно на облачном сервере от JetBrains, Space! И это решит одну из главных жалоб юзеров - потребление кучи ресурсов(памяти и проца).
Я сегодня таки поставил и пощупал. Котлин оно понимает весьма неплохо. Интерфейс модный-молодежный. Как у VSCode. Настройки хранятся в json-файле. Как у VSCode. Да и smart mode напоминает language server протоколы, которые тоже популярны в вскоде. Но это JetBrains! Они умеют делать не только хорошо, а лучше всех. Надо еще подождать и посмотреть. Настроек очень мало. Плагинов пока никаких нет и апишки к ним не опубликованы.
Решили это таким образом: появился некий бекэнд(решарпер), который понимает код, генерит подсказки и подсвечивает ошибки, и фронтэнд - сама оболочка, UI. Общаются они по внутреннему протоколу. JB ходили на конфы и рассказывали как сложно им оптимизировать это, чтобы работало с приемлемой скоростью, но с годами проблемы были решены, и насколько мне известно Rider потихоньку отвоевывает рынок у Visual Studio, хотя цифр конкретных у меня нет.
Архитектура Rider вынужденно повторила архитектуру современных SPA веб-приложений. И вроде бы получился некий уродец с кучей проблем. Тут и перформанс, и плагин нормальный написать - тоже надо и фронтэнд часть и бэкэнд. Но кто-то в JB решил, что это не баг, а фича!
И появился Fleet - "Next-generation IDE by JetBrains". Архитектура точно такая же - интерфейс это фронтэнд, а вся умнота(там это называется Smart mode) - бекэнд. А фича в том, что бэк можно разместить как на компе юзера(и тогда получим более-менее обычную JetBrains IDE), а можно на облачном сервере от JetBrains, Space! И это решит одну из главных жалоб юзеров - потребление кучи ресурсов(памяти и проца).
Я сегодня таки поставил и пощупал. Котлин оно понимает весьма неплохо. Интерфейс модный-молодежный. Как у VSCode. Настройки хранятся в json-файле. Как у VSCode. Да и smart mode напоминает language server протоколы, которые тоже популярны в вскоде. Но это JetBrains! Они умеют делать не только хорошо, а лучше всех. Надо еще подождать и посмотреть. Настроек очень мало. Плагинов пока никаких нет и апишки к ним не опубликованы.
👍17🤔3
https://t.me/tg_5minphp/1306
А я бы спать не мог спокойно, зная что такое дерьмо у меня в коде...
Upd: в комментариях подсказали, что Олег Фогель это один из руководителей разработки в 1С) это прекрасно
А я бы спать не мог спокойно, зная что такое дерьмо у меня в коде...
Upd: в комментариях подсказали, что Олег Фогель это один из руководителей разработки в 1С) это прекрасно
Telegram
Пятиминутка PHP
Актуально сегодня
😁25🔥5
Код Laravel Idea потихоньку приходит к канонам. К слоям. Я начал разделять его на отдельные проекты.
* Проект с общими хелперами, которые пригодятся другому плагину(сюда уедут процентов 10 кода).
* Проект с всей логикой Laravel Idea(тут будет 85% кода).
* Проект для связки Laravel Idea с PhpStorm.
* Проект для связки Laravel idea с Qodana.
Это все равно когда-нибудь произошло бы. Но теперь понадобилось для двух целей - специальной версии плагина для Qodana(CI тулзы от JetBrains) и нового плагина, который уже давно хотел начать, но вот сейчас только руки дошли.
Когда начинал писать плагин, думал что проект совсем иной и общего с веб-проектами с их слоями Application layer и другими нет. Тут очень все завязано на внутреннюю структуру IDE. Но чем дальше в лес, тем больше приходит понимание, что структура там тоже важна. И вырисовывались слои. А новые требования быстро помогли осознать, что пора их отделить уже физически.
* Проект с общими хелперами, которые пригодятся другому плагину(сюда уедут процентов 10 кода).
* Проект с всей логикой Laravel Idea(тут будет 85% кода).
* Проект для связки Laravel Idea с PhpStorm.
* Проект для связки Laravel idea с Qodana.
Это все равно когда-нибудь произошло бы. Но теперь понадобилось для двух целей - специальной версии плагина для Qodana(CI тулзы от JetBrains) и нового плагина, который уже давно хотел начать, но вот сейчас только руки дошли.
Когда начинал писать плагин, думал что проект совсем иной и общего с веб-проектами с их слоями Application layer и другими нет. Тут очень все завязано на внутреннюю структуру IDE. Но чем дальше в лес, тем больше приходит понимание, что структура там тоже важна. И вырисовывались слои. А новые требования быстро помогли осознать, что пора их отделить уже физически.
👍23🔥7
Forwarded from PHP Digest
«Своя игра» по PHP на канале CutCode
Вы можете задать сейчас вопросы участникам викторины.
Самые интересные вопросы будут разобраны на игре, а их авторы получат возможность поучаствовать в следующей игре и получить мерч!
🕛 13 марта в 19:00 (мск)
🔹 Александр Макаров
🔹 Кирилл Несмеянов
🔹 Адель Файзрахманов
🎬 https://www.youtube.com/watch?v=WNIAO0kEk7U
Вы можете задать сейчас вопросы участникам викторины.
Самые интересные вопросы будут разобраны на игре, а их авторы получат возможность поучаствовать в следующей игре и получить мерч!
🕛 13 марта в 19:00 (мск)
🔹 Александр Макаров
🔹 Кирилл Несмеянов
🔹 Адель Файзрахманов
🎬 https://www.youtube.com/watch?v=WNIAO0kEk7U
👍16👎2❤1
В твиттере высветился пост одного стартапера и меня порадовала концовка. Он там рассказывает как делал десятки стартапов. Вон 21 стартап за 2 года.
Ничего толком не приносило денег до тех пор пока... он не выпустил сервис для быстрой выкатки стартапов! "The NextJS boilerplate with all you need to build your SaaS, AI tool, or any other web app and make your first $ online fast."
Это теперь приносит ему $75k в месяц. Типичный пример когда человек не смог копать золото сам, но стал продавать лопаты другим)
Ничего толком не приносило денег до тех пор пока... он не выпустил сервис для быстрой выкатки стартапов! "The NextJS boilerplate with all you need to build your SaaS, AI tool, or any other web app and make your first $ online fast."
Это теперь приносит ему $75k в месяц. Типичный пример когда человек не смог копать золото сам, но стал продавать лопаты другим)
🔥37😁24👍5👌1
Мой маленький CI для сборки Laravel Idea выглядит так. Простой HTML как в бородатые года. Никакого CSS. (Сегодня ночью собирался 8.1.4 релиз, уже доступен на маркетплейсе)
Как думаете сколько памяти в Хроме занимает эта страница? 57 Мб!! Что там? Как? Для чего? Очень поразила меня эта инфа...
Как думаете сколько памяти в Хроме занимает эта страница? 57 Мб!! Что там? Как? Для чего? Очень поразила меня эта инфа...
🔥10😐3🤔2
Давно не запускал полный набор тестов в плагине на локальном компе. На Continuous Integration сервере запускаются после каждого git push, поэтому не парился. Но недавно запустив, осознал, что уже больше недели там есть тест, который падает. А на CI работает!
Причина банальная: когда на компьютере часовой пояс UTC, то тест нормально работает, а когда отличается - падает.
Вообще, такой ситуации быть не должно, и CI должен ловить такое, но что сделать для этого? Банально поставить ему другой часовой пояс? Крупные компании решают эту проблему как либо?
Причина банальная: когда на компьютере часовой пояс UTC, то тест нормально работает, а когда отличается - падает.
Вообще, такой ситуации быть не должно, и CI должен ловить такое, но что сделать для этого? Банально поставить ему другой часовой пояс? Крупные компании решают эту проблему как либо?
🤯9
Читаю Аркадия Морейниса. Не каждым постом, но регулярно выдает что-нибудь точное. Вот примерное обьяснение почему мне крайне не хочется делать что-то для VS Code - https://t.me/temno/6239
Среди людей, выбирающих бесплатное(вскод вместо шторма), будет крайне мало тех, кто готов платить за плагин для Laravel.
Среди людей, выбирающих бесплатное(вскод вместо шторма), будет крайне мало тех, кто готов платить за плагин для Laravel.
Telegram
Тёмная сторона / Темнографика
Хейтеры будут хейтить, халявщики будут халявить, а покупатели будут покупать
1. Наткнулся на историю, когда один чувак решил организовывать конференции, но никак не мог понять, где найти на них спонсоров. Пока он не додумался посмотреть, кто из компаний…
1. Наткнулся на историю, когда один чувак решил организовывать конференции, но никак не мог понять, где найти на них спонсоров. Пока он не додумался посмотреть, кто из компаний…
👍17😁1