(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
307 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Продолжается перерыв в теме микросервисов.
Сегодня будет немного холивара)

Можно ли использовать static методы?

Исторически static-и прошли 3 стадии в своем восприятии.

1 этап: о круто, можно не создавать объект, давайте все методы делать статическими.
Если что - я конечно утрирую насчет всех, но static-и активно использовались, это факт, который легко увидеть в legacy коде. Еще факт: static-и есть во многих языках, что как бы намекает. Даже в Kotlin они есть, просто выглядят странно - я про companion object.

2 этап: static-и трудно тестировать, это антипаттерн, не надо их использовать. Ну разве что для Util классов, и то ...
Вот пример, демонстрирующий почему возникают такие мысли.
Возьмем другой антипаттерн - синглетон.

class Singleton {
private static final instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
....
}
Сразу скажу - это не одна из простейших реализаций, не потокобезопасная, взятая для примера, так делать не надо.

Предположим, мы хотим сделать вместо Singleton заглушку для теста. Ну например, он ходит в БД или читает данные из файла, а мы хотим, чтобы тесты работали быстро.
Можно сделать так:
class TestSingleton extends Singleton {
private static final testInstance = new TestSingleton();
public static Singleton getTestInstance() {
return testInstance;
}
....
}
Но это работает только если Sigleton можно как-то передать в тестируемый класс, он же System under Test (SUT).
А если это зависимость зависимости SUT? Или в более общем случае его нельзя передать через public API?
Основная проблема в том, что static методы не наследуются, а следовательно переопределить их нельзя. Можно создать метод с тем же именем, но вызываться будет метод того класса, который указан в конкретном куске кода. Или декларируемого, а не фактического класса переменной, поля или параметра, если static вызывается на объекте. В этом плане Java позволяя вызывать static метод из объекта только путает людей( К слову, в Kotlin так нельзя.

Есть конечно грязные хаки с мокированием static методов, даже Mockito это умеет. Но тот факт, что для включения этой фичи нужно добавить настройку в classpath https://www.baeldung.com/mockito-mock-static-methods говорит о том, что авторы Mockito не рекомендуют так делать.

3 этап, наше время: все не так однозначно. Точнее однозначно вот что: если static метод используется в паре со static полями - это точно зло.
И самостоятельное создание синглетонов тоже зло) Это я на всякий случай уточняю)
Но если присмотрется к вот такому static методу:
1) он не имеет доступа к полям объекта по определению
2) в классе нет static полей как я писал выше
3) пусть метод не имеет побочных эффектов. Т.е. не лезет в БД, в файловую систему, в другие сервисы
Т.е метод получает что-то на вход, вычисляет что-то и возвращает результат.
Это типичный метод Util класса, да.
Но еще это определение функции из математики. А функция - это функциональное программирование. А Java начиная с 8 версии умеет передавать ссылки на функции. И хотя в ней нет функциональных типов, но есть функциональные интерфейсы, которые делают тоже самое, просто немного с большим количеством кода. Java же, все как мы любим)

Подводя итог - считать static злом не надо. Надо лишь правильно его использовать.

#interview_question #holy_war #java #kotlin
Всем привет!

Возвращаясь к Kotlin и переходу на него с Java.
Может возникнуть вопрос - как начать писать в стиле Kotlin?
Ответ - начни с официальной документации.

Ключевые отличия от Java по мнению авторов: https://kotlinlang.org/docs/comparison-to-java.html
Идиомы - часто используемые куски кода, можно сказать низкоуровневые паттерны языка: https://kotlinlang.org/docs/idioms.html
Coding conventions https://kotlinlang.org/docs/coding-conventions.html
Примеры кода от авторов языка: https://play.kotlinlang.org/byExample/01_introduction/01_Hello%20world
Migration guide с Java https://kotlinlang.org/docs/java-to-kotlin-idioms-strings.html

P.S. Надо было раньше этот пост написать)
P.P.S Документацию иногда стоит почитать)
P....S А для самых хардкорных - как известно Kotlin написан на Kotlin. https://github.com/JetBrains/kotlin

#java #kotlin
Всем привет!

Снова про Kotlin.
Возможно не все знают, что в Kotlin изобрели свои стримы - sequences https://kotlinlang.org/docs/sequences.html#sequence.
Зачем? Во-первых есть Kotlin/JS и Kotlin/Native, где нет JDK и стримов. А еще Kotlin может работать на Java 6.
А во-вторых - реализация стримов сделана под Java, что приводит к более сложному API, чем "принято" в Kotlin и проблемами с null safety из-за использования типов Java под капотом. Но у стримов есть и плюсы) Сравнение см. https://proandroiddev.com/java-streams-vs-kotlin-sequences-c9ae080abfdc

P.S. Есть некая ирония в том, что стримы, которые сильно упрощают код Java, выглядят все же более тяжеловесно по сравнению с реализацией в Kotlin)

#kotlin #java
Всем привет!

Небольшое замечание. О важности проблемы null safety в Java говорит вот этот список различных видов @Null\@NotNull аннотаций Java, которые поддерживает Kotlin при проверке типов: https://kotlinlang.org/docs/java-interop.html#nullability-annotations К слову, все они не входят в стандартную библиотеку Java.

#java #kotlin #nullsafety
Всем привет в 2023 году!

Уже писал про плюсы Kotlin, забыл про еще один - язык подталкивает к правильному написанию кода по умолчанию. Что имеется в виду:

1) все типы по умолчанию not null, для nullable типа нужно добавить ? к названию типа. String и String? Что дает: уменьшает число переменных с null в программе, следовательно, уменьшает число NPE
2) все коллекции по умолчанию immutable, чтобы создать изменяемую коллекцию надо использовать метод с mutable в названии: listOf(1,2) и mutableListOf(1,2). Что дает: упрощает оптимизацию байт-кода компилятором или JVM.
3) все классы и методы по умолчанию final, чтобы сделать открытый для расширения метод или класс - нужно указать ключевое слово open. Это приводит к тому, что открытыми будут только те классы и методы, которым это точно нужно)

Сюда же я бы добавил паттерны, реализованные в языке Kotlin. По сути это и синтаксический сахар, и эталонные реализации по умолчанию, уменьшающие вероятность ошибок при самостоятельной реализации:
4) синглтон - объявление класса-синглтона с помощью ключевого слова object
5) делегат - делегирование функционала класса или отдельного property через ключевое слово by

Почему важно по умолчанию показывать, как писать код правильно?
Приведу два примера:
1) Когда давным давном в далекой галктике Borland была среды быстрой разработки (RAD) Delphi. Хорошая была IDE, сделала одну большую ошибку - сильно завязалась на Windows и проиграла конкуренцию Visual Studio при массовом переходе на .NET.
Но был еще один серьезный недостаток. При создании нового проекта по умолчанию создавалось 3 файла: файл проекта, файл формы с UI компонентами и файл для обработчиков событий на форме. БольшАя часть разработчиков в файле для обработчиков хранила и бизнес-логику - Model + Controller. Лично я первое время делал именно так((( А всего-то надо было сделать еще один файл, назвать его скажем Logic.pas.
2) Еще похожий случай более близкий к нам по времени. Есть такой язык PHP. Язык простой в обучении, без компиляции, с нестрогой типизацией, с мощными и простыми средствами для обработки HTTP запросов, генерации HTML и работой с БД. Такая простота приводит к тому, что опять же многие PHP разработчики не думают о разделении кода по классам. Получаются огромные php скрипты, где смешаны M, V и C.

#kotlin #languages #nullsafety