Всем привет!
Продолжается перерыв в теме микросервисов.
Сегодня будет немного холивара)
Можно ли использовать 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
Продолжается перерыв в теме микросервисов.
Сегодня будет немного холивара)
Можно ли использовать 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
Baeldung
Mocking Static Methods With Mockito | Baeldung
Explore a couple of examples of how we can use Mockito to mock static methods.
Всем привет!
Возвращаясь к 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 и переходу на него с 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
GitHub
GitHub - JetBrains/kotlin: The Kotlin Programming Language.
The Kotlin Programming Language. . Contribute to JetBrains/kotlin development by creating an account on GitHub.
Всем привет!
Снова про 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
Снова про 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
Medium
Java Streams vs. Kotlin Sequences
Java streams are available to use in Kotlin when targeting JDK 8 or later for backend applications. A common question is whether to use…