assert not for public methods
От: Hard_Club  
Дата: 09.01.14 10:04
Оценка:
Недавно прочитал в одной книге, что с помощью assert нельля проверять аргументы в публичных методах, т.к. его можно оключить, а public-методы должны всегда проверять входящие параметры. Откуда взялось такое правило? Кто его установил?
Re: assert not for public methods
От: Blazkowicz Россия  
Дата: 09.01.14 10:13
Оценка:
Здравствуйте, Hard_Club, Вы писали:

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

http://rsdn.ru/forum/java/2893010
Автор: Antei
Дата: 27.03.08


H_C>Откуда взялось такое правило?

В документации написано к assert-ам.

H_C>Кто его установил?

Блох? А тебе зачем?
https://jcp.org/en/jsr/detail?id=41
Re: assert not for public methods
От: StanislavK Великобритания  
Дата: 09.01.14 10:14
Оценка: +1
Здравствуйте, Hard_Club, Вы писали:

H_C>Недавно прочитал в одной книге, что с помощью assert нельля проверять аргументы в публичных методах, т.к. его можно оключить, а public-методы должны всегда проверять входящие параметры. Откуда взялось такое правило? Кто его установил?


Мое мнение, что ассерты вообще больная идея и их нельзя использовать. Проверять что-то в дебаге и не проверять потом в продакшине это... не хорошо.
Re[2]: assert not for public methods
От: Hard_Club  
Дата: 09.01.14 10:22
Оценка:
H_C>>Кто его установил?
B>Блох? А тебе зачем?
B>https://jcp.org/en/jsr/detail?id=41

Да, просто assert в данном случае самое оно, по-моему. Мы же проверяем нарушение контракта, а не корректность входных параметров.
Re[2]: assert not for public methods
От: devcoach  
Дата: 09.01.14 10:27
Оценка:
Здравствуйте, StanislavK, Вы писали:

SK>Мое мнение, что ассерты вообще больная идея и их нельзя использовать. Проверять что-то в дебаге и не проверять потом в продакшине это... не хорошо.

Это вы очень зря. Ассерты по своей сути — легковесные тесты. Причем они могут проверять такие вещи, до которых тестами никогда не докопаешься. Но при этом, разумеется, валидировать ими параметры пользовательского API — не вариант. Они нужны для отслеживания работы непубличных кишок.
Re[3]: assert not for public methods
От: devcoach  
Дата: 09.01.14 10:39
Оценка: -1
Здравствуйте, Hard_Club, Вы писали:

H_C>Да, просто assert в данном случае самое оно, по-моему. Мы же проверяем нарушение контракта, а не корректность входных параметров.

Вы неправильно трактуете публичные методы. Это не методы с сигнатурой public, а методы, с которыми работает конечный пользователь. Это большая разница. Действительно, валидировать ассертами значения, которые передал пользователь нельзя. А валидировать значения, переданные в public метод какого-то внутреннего класса можно, если существуют четкие и устоявшиеся ограничения, когда и кто его может вызывать.
Re[4]: assert not for public methods
От: Hard_Club  
Дата: 09.01.14 10:46
Оценка:
Здравствуйте, devcoach, Вы писали:

D>Здравствуйте, Hard_Club, Вы писали:


H_C>>Да, просто assert в данном случае самое оно, по-моему. Мы же проверяем нарушение контракта, а не корректность входных параметров.

D>Вы неправильно трактуете публичные методы. Это не методы с сигнатурой public, а методы, с которыми работает конечный пользователь. Это большая разница. Действительно, валидировать ассертами значения, которые передал пользователь нельзя. А валидировать значения, переданные в public метод какого-то внутреннего класса можно, если существуют четкие и устоявшиеся ограничения, когда и кто его может вызывать.

О!
Теперь ясно. Но как тогда по-научному называется методы с сигнатурой public?
Re[3]: assert not for public methods
От: StanislavK Великобритания  
Дата: 09.01.14 10:48
Оценка:
Здравствуйте, devcoach, Вы писали:

D>Здравствуйте, StanislavK, Вы писали:


SK>>Мое мнение, что ассерты вообще больная идея и их нельзя использовать. Проверять что-то в дебаге и не проверять потом в продакшине это... не хорошо.

D>Это вы очень зря. Ассерты по своей сути — легковесные тесты. Причем они могут проверять такие вещи, до которых тестами никогда не докопаешься. Но при этом, разумеется, валидировать ими параметры пользовательского API — не вариант. Они нужны для отслеживания работы непубличных кишок.

Не понял. Что это такое до чего тестами не докопаешься? И при чем тут вообще тесты?
Есть проверка на что-то такое, что не должно случиться и эта проверка радостно выкилывается в продакшен коде, т.е. случться жопа, а никто и не узнает. Прекрасно!

Есть хотите поспорить, то давай-те примеры и обсудим, что там лучше зделать вместо ассерта.
Re[4]: assert not for public methods
От: devcoach  
Дата: 09.01.14 11:09
Оценка: +2
Здравствуйте, StanislavK, Вы писали:

SK>Не понял. Что это такое до чего тестами не докопаешься? И при чем тут вообще тесты?

Тесты тут при том, что assert'ы созданы для помощи в тестировании приложения при его разработке.

SK>Есть проверка на что-то такое, что не должно случиться и эта проверка радостно выкилывается в продакшен коде, т.е. случться жопа, а никто и не узнает. Прекрасно!

Еще раз, assert — инструмент для тестирования в момент разработки. Так же, как и обычные юнит-тесты.

SK>Есть хотите поспорить, то давай-те примеры и обсудим, что там лучше зделать вместо ассерта.

Да у меня весь проект в ассертах, и мы регулярно им говорим спасибо. Цель ассерта очень и очень проста. Есть у вас какая-то внутренняя логика. И вы знаете, что на определенном шаге в конкретном месте всегда должно выполняться определенное условие. Отлично, вы туда ставите assert. Теперь если какой-нибудь Вася, внедряя свою новую фияу, сломает это условие, он сразу же словит эксепшн, даже до того, как он написал тесты. Ведь это только в сказках бывает так, что у нас все закрыто интерфейсами, все можно оттестировать, а единороги какают радугой.
Более того, какие-то вещи в принципе нельзя достоверно оттестировать. Например, многопоточные кейсы. Если у вас есть какая-то замороченная многопоточная логика, то как вы не изголяйтесь, вы не сможете написать тест, который на 100% гарантирует вам отсутствие в коде гонок. А ассершны могут вам дегко эту уверенность увеличить.

Резюмируя:
1) assert — это инструмент для тестирования приложения на этапе разработки;
2) требует минимальных трудозатрат;
3) легко проникает в труднодоступные для классических тестов места.

Поэтому мне вообще непонятно, о чем тут спорить. Разумеется, такой удобный инструмент нужно использовать, тут даже думать не о чем.
Re[5]: assert not for public methods
От: Blazkowicz Россия  
Дата: 09.01.14 11:11
Оценка:
Здравствуйте, devcoach, Вы писали:

D>Поэтому мне вообще непонятно, о чем тут спорить. Разумеется, такой удобный инструмент нужно использовать, тут даже думать не о чем.

Вопрос в том как огородить код от misuse assert-ов. Мало ли кому взбредет в голову их не по назначению использовать.
Re[6]: assert not for public methods
От: devcoach  
Дата: 09.01.14 11:31
Оценка:
Здравствуйте, Blazkowicz, Вы писали:

B>Вопрос в том как огородить код от misuse assert-ов. Мало ли кому взбредет в голову их не по назначению использовать.

Ну это да, но выстрелить себе в ногу можно любым инструментом, assert не является исключением.
Re[5]: assert not for public methods
От: StanislavK Великобритания  
Дата: 09.01.14 11:34
Оценка: +1
Здравствуйте, devcoach, Вы писали:

SK>>Не понял. Что это такое до чего тестами не докопаешься? И при чем тут вообще тесты?

D>Тесты тут при том, что assert'ы созданы для помощи в тестировании приложения при его разработке.
Это просто ярлык. Вседа верите на слово? Наверно были большим фанатом персистент бинов?

SK>>Есть проверка на что-то такое, что не должно случиться и эта проверка радостно выкилывается в продакшен коде, т.е. случться жопа, а никто и не узнает. Прекрасно!

D>Еще раз, assert — инструмент для тестирования в момент разработки. Так же, как и обычные юнит-тесты.
Еще раз см. выше. То, что вы это повторяете, оно не станет правдой. assert — просто бесполезная и опасная штука, которую некоторые товарищи используют для якобы тестирования. Опасная она потому, что вместо того, чтобы писать надежный код с проверками, люди начинают городить ассерты и думают, что все будет пучком.

SK>>Есть хотите поспорить, то давай-те примеры и обсудим, что там лучше зделать вместо ассерта.

D>Да у меня весь проект в ассертах, и мы регулярно им говорим спасибо. Цель ассерта очень и очень проста. Есть у вас какая-то внутренняя логика. И вы знаете, что на определенном шаге в конкретном месте всегда должно выполняться определенное условие. Отлично, вы туда ставите assert. Теперь если какой-нибудь Вася, внедряя свою новую фияу, сломает это условие, он сразу же словит эксепшн, даже до того, как он написал тесты. Ведь это только в сказках бывает так, что у нас все закрыто интерфейсами, все можно оттестировать, а единороги какают радугой.
D>Более того, какие-то вещи в принципе нельзя достоверно оттестировать. Например, многопоточные кейсы. Если у вас есть какая-то замороченная многопоточная логика, то как вы не изголяйтесь, вы не сможете написать тест, который на 100% гарантирует вам отсутствие в коде гонок. А ассершны могут вам дегко эту уверенность увеличить.
Да это бред како-то. Если у вас есть гонка, то значит получится так, что данные будут в некорректном состоянии, что значит, что надо срочно падать или, хотябы, писать о проблеме в лог, а не довольствоваться выкинутым в релизе ассертом.

D>Резюмируя:

D>1) assert — это инструмент для тестирования приложения на этапе разработки;
D>2) требует минимальных трудозатрат;
D>3) легко проникает в труднодоступные для классических тестов места.
Вы не книжку пишете. Вне контекста, это просто пустые тезисы. Давайте ограничемся примерами того, где вам кажется, что этот иструмент работает и обсудим. Пример с многопоточностью пока выглядит не очень.

D>Поэтому мне вообще непонятно, о чем тут спорить. Разумеется, такой удобный инструмент нужно использовать, тут даже думать не о чем.

О нем надо забыть и больше никода не вспоминать.
Re[4]: assert not for public methods
От: Blazkowicz Россия  
Дата: 09.01.14 11:48
Оценка:
Здравствуйте, devcoach, Вы писали:

D>Вы неправильно трактуете публичные методы. Это не методы с сигнатурой public, а методы, с которыми работает конечный пользователь. Это большая разница. Действительно, валидировать ассертами значения, которые передал пользователь нельзя. А валидировать значения, переданные в public метод какого-то внутреннего класса можно, если существуют четкие и устоявшиеся ограничения, когда и кто его может вызывать.


Позволю не согласиться. С точки зрения использования assert-ов разница между public и private методами очевидна.
public метод может вызвать кто угодно и когда угодно. Поэтому его логика зависит от параметров и состояния объекта. Поэтому вместо assert-ов в них стоит использовать Runtime исключения и прочую валидацию.
private метод вызывается только другими методами этого же класса. Поэтому параметры private метода и состояние объекта в момент вызова private метода предопределены.
assert-ы помогают выявить нарушения в вызове private методов.

В целом, соглашуюсь с точкой зрения StanislavK. Практического и полезного применения assert-ов в Java пока не видел.
Re[5]: assert not for public methods
От: Hard_Club  
Дата: 09.01.14 11:51
Оценка:
Checked или Unchecked исключения?
Re[6]: assert not for public methods
От: Blazkowicz Россия  
Дата: 09.01.14 11:53
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Checked или Unchecked исключения?

На вкус и цвет каждому свои фломастеры.
Re[6]: assert not for public methods
От: Blazkowicz Россия  
Дата: 09.01.14 11:54
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Checked или Unchecked исключения?

Checked исключения это всегда логика приложения.
assert никогда не должен быть логикой приложения.
Напрашивает логический вывод.
Re[6]: assert not for public methods
От: devcoach  
Дата: 09.01.14 12:00
Оценка:
Здравствуйте, StanislavK, Вы писали:

SK>Это просто ярлык. Вседа верите на слово? Наверно были большим фанатом персистент бинов?

Понятия не имею, о чем вы.

>Еще раз см. выше. То, что вы это повторяете, оно не станет правдой. assert — просто бесполезная и опасная штука, которую некоторые товарищи используют для якобы тестирования. Опасная она потому, что вместо того, чтобы писать надежный код с проверками, люди начинают городить ассерты и думают, что все будет пучком.

Вы упорно не можете или не хотите услышать, что я пытаюсь до вас донести. Где я написал, что какие-то проверки нужно заменять ассертами? Если у вас в коде есть какая-то проверка, по итогам которой хотите бросить пользователю эксепшн, то, разумеется, ассерты использовать нельзя. В десятый раз повторяю: ассерты — это инструмент для тестирования, а не для управления реальной логикой приложения. Что такое тестирование вы понимаете? Следуя вашей выернутой наизнанку логике, я могу так же сказать: "А нафига нужны тесты вообще? Надо же просто проверку в коде, а потом эксепшн бросить!? Ведь тесты в продакшне не гоняются!" Ну конечно, они не гоняются. Их используют в процессе разработки, что бы отловить ошибки. И они точно так же, как и ассерты, не влияют на логику приложения в продакшне.

>Да это бред како-то. Если у вас есть гонка, то значит получится так, что данные будут в некорректном состоянии, что значит, что надо срочно падать или, хотябы, писать о проблеме в лог, а не довольствоваться выкинутым в релизе ассертом.

См. выше.

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

Элементарнейший пример с многопоточностью. Есть какая-то заумная многопоточная логика. Есть некий метод, который можно вызывать только внутри критической секции. Если он вызван вне критической секции, то это косяк. То есть, на примере с synchronized, не сам этот метод synchronized, а он должен быть вызван внутри synchronized (надеюсь, идея понятна). Вот я написал два метода, method1() и method2(), все круто. А потом пришел Вася, и зафигачил method3(), в котором забил на синхронизацию. Не вопрос, мой ассершн сразу обрубит ему эту возможность:

public class Service {

    public void method1() {
        // ...
        synchronized (this) {
            // ...
            someNotThreadSafeLogic();
            // ...
        }
        // ...
    }

    public synchronized void method2() {
        // ...
        someNotThreadSafeLogic();
        // ...
    }

    public void method3() {
        // ...
        someNotThreadSafeLogic();
        // ...
    }

    private void someNotThreadSafeLogic() {
        assert Thread.holdsLock(this);
        // ...
    }
}

Это не валидация чего-то. Это не изменение логики программы. Это просто предохранитель, не более.
Re[6]: assert not for public methods
От: StanislavK Великобритания  
Дата: 09.01.14 12:00
Оценка:
Здравствуйте, Hard_Club, Вы писали:

H_C>Checked или Unchecked исключения?

Это вопрос не простой. На вкус и цвет. Я предпочитаю Runtime по причине того, что проще и код выглядит лучше. Но про них проще забыть, не заметить... правда плохо ли это... если код написано корректно, то проблем в любом случае быть не должно.
Главное в исключениях, это то, что если исключение не просто "все кончено", то оно должно быть документированно.
Re[5]: assert not for public methods
От: avpavlov  
Дата: 09.01.14 12:02
Оценка:
B> Практического и полезного применения assert-ов в Java пока не видел.

Я видел. У нас findbugs встроен в сборку, и у него есть проверка, что код проверяет возвращаемое значение queue.offer, потому что для bounded queue там возвращается false, если элемент был отвергнут.

Для unbounded queue эта проверка бессмысленна, но findbugs об этом не знает.

"assert queue.offer" позволяет успокоить findbugs без @SuppressWarning-а, который мне не нравится
Re[7]: assert not for public methods
От: avpavlov  
Дата: 09.01.14 12:06
Оценка:
D>Это не валидация чего-то. Это не изменение логики программы. Это просто предохранитель, не более.

Хороший такой предохранитель, который кидает "AssertionError extends Error", который с 99% вероятностью пролетит мимо всех кэтчей и вырубит поток. Или у вас везде Throwable ловится?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.