Касательно 5-го пункта: ключевое слово finalи как его использовать не является малоизвестный особенностью Java. Если вам действительно хочется защитить массив от изменений, то воспользуйтесь List<Integer> вместо int[] и отдавайте клиенту защищенную оболочку через Collections.unmodifiableList(List).
Надеюсь, у вас в самом начале формы ярко-красным висит предупреждение:
«пользователь, имей ввиду: некоторые — только нам известные — поля ввода мы незаметненько корректируем после твоего ввода. Поэтому перечитывай все вдумчиво по два раза, даже если тебе кажется, что все введено правильно!»
Простите, а что символизирует перечеркнутая груша в качестве КДПВ? Вкупе с двусмысленным названием (обсудили выше) полностью сбивает с толку, учитывая выводы в конце статьи… Груша с вопросительным знаком или же «груша» vs «яблоко» было бы ближе к тону статьи.
Каскадный релиз snapshot'ов разных библиотек?! Либо это не разные библиотеки, а модули одного проекта (и тогда maven-release-plugin зарелизит все модули «каскадно»), либо Вы недопонимаете, как важно беречь независимость разных библиотек, даже если их реализацией занимается одна команда.
В текущем проекте я организовал следующий подход:
Допустим имеется проект A-1.0-RC1-snapshot, который использует B-alpha-2-snapshot и С-alpha-7-snapshot.
Прежде чем заморозить проект A, я замораживаю проект B:
B-alpha-2-snapshot => B-alpha-2 => B-alpha-3-snapshot
Далее прошу owner-a проекта C (это другая команда) также выпустить промежуточный релиз:
С-alpha-7-snapshot => С-alpha-7 = С-alpha-8-snapshot
После того как все зависимости стабилизированы и заморожены можно замораживать проект A:
A-1.0-RC1-snapshot => A-1.0-RC1 => A-1.0-RC2-snapshot
И еще раз: плагина который делал бы каскадный релиз по нескольким проектам не существует, и я очень надеюсь что его никогда не появится.
Вы уж простите меня за мой французский, но этот ваш ван Элбург — последний болван!
Он даже не удосужился вникнуть в принцип измерения Common View, разработанный в 1980 году NIST.
В церне сидят не круглые дебилы, и разработанный метод GPS Bases Time Link Calibrationразумеется учитывает релятивистские эффекты!
Более того, без учета этих эффектов даже автомобильная навигация давала бы точность ± 500 метров.
Этих эффектов, между прочим, немного больше чем учел товарищ Элбург. Помимо релятивистского эффекта Доплера присутствует также Shapiro Propagation Delay и пр.
И уж совсем смешны умозаключения этого последнего болвана в свете того, что экспериментаторы подстраховались и проверили точность измерений при помощи поистине точнейшей установки с двумя цезиевыми часами немецкого института «мер и весов» www.ptb.de
Результаты совпали с GPS методом, с точностью до 2 нс.
Зачем изобретать велосипед, если есть MVP?
Вот вам безупречный с точки зрения архитектуры пример реализации MVP паттерна: www.logicdevelopment.net/blog/?p=16
Но согласитесь, даже для проектов внутри Вашей организации: сегодня вы знаете, что везде используется java.util.logging, но что будет завтра — этого не знает никто. Вот захочется вам через пару лет 10 кратного перформанса или особой реализации с учетом специфики Java EE или OSGi или что-то еще… а у вас везде JUL.
Хорошая вводная статья. Хотелось бы обратить внимание на еще один, архи-важный момент: логирование в библиотеках отличается коренным образом от логирования в конечном приложении.
В идеале библиотека (коих в приложении может быть больше чем одна штука) не навязывает мне использование какой-либо конкретной реализации логирования, а пользуется нейтральным интерфейсом, оставляя выбор реализации за конечным приложением (именно эту возможность дают SLF4J и динозавр commons logging).
И уж совсем печально видеть порой библиотеки, которые не только берут ответственность в выборе реализации логирования на себя, но вдобавок еще и перенимают на себя всю конфигурацию.
Пожалуйста, избегайте подобные фокусы. Помните, каждый раз, когда вы компилируете такой код, где-то умирает маленький котенок.
Жаль что не упомянули OSGi. Эта «экосистема» имеет на сегодняшний день наиболее продуманные и удобные инструменты конфигурации по сравнению с Java SE и Java EE.
Назвать хотя-бы Configuration Admin Service и Fragments.
Я очень люблю hamcrest, и именно по этой причине предпочитаю полноценный пакет hamcrest-all базовому пакету hamcrest-core. Но если добавить в classpath одновременно обе библиотеки, то получим очень неприятные конфликты времени исполнения.
Именно это происходит, если в classpath есть org.hamcrest:hamcrest-all и junit:junit, т.к. последний уже содержит в себе некоторые hamcrest-классы.
Разработчики JUnit советуют вкупе с hamcrest-all использовать исключительно пакет junit:junit-dep, который не содержит в себе hamcrest классов. Maven кофиг выглядит примерно так:
Но тут есть подвох: пакет junit-dep имеет compile-scope зависимость от пакета hamcrest-core, хотя логичнее был бы provided-scope. Как следствие, в class-path попадают не два, а три пакета:
junit-dep-4.9
hamcrest-core-1.1
hamcrest-all-1.2
со всеми вытекающими последствиями.
Единственное противоядие от недуга, «выпиливать» ненужный hamcrest-core в ненужной, устаревшей версии. Примерно так:
p.s. мои опасения насчет 4.9 подтвердились. hamcrest-core по-прежнему включен в compile-scope пакета junit-dep. Видимо придется писать команде баг-репорт, благо ребята сами вызвались поддерживать maven пакеты…
«пользователь, имей ввиду: некоторые — только нам известные — поля ввода мы незаметненько корректируем после твоего ввода. Поэтому перечитывай все вдумчиво по два раза, даже если тебе кажется, что все введено правильно!»
В текущем проекте я организовал следующий подход:
Допустим имеется проект A-1.0-RC1-snapshot, который использует B-alpha-2-snapshot и С-alpha-7-snapshot.
Прежде чем заморозить проект A, я замораживаю проект B:
B-alpha-2-snapshot => B-alpha-2 => B-alpha-3-snapshot
Далее прошу owner-a проекта C (это другая команда) также выпустить промежуточный релиз:
С-alpha-7-snapshot => С-alpha-7 = С-alpha-8-snapshot
После того как все зависимости стабилизированы и заморожены можно замораживать проект A:
A-1.0-RC1-snapshot => A-1.0-RC1 => A-1.0-RC2-snapshot
И еще раз: плагина который делал бы каскадный релиз по нескольким проектам не существует, и я очень надеюсь что его никогда не появится.
Он даже не удосужился вникнуть в принцип измерения Common View, разработанный в 1980 году NIST.
В церне сидят не круглые дебилы, и разработанный метод GPS Bases Time Link Calibration разумеется учитывает релятивистские эффекты!
Более того, без учета этих эффектов даже автомобильная навигация давала бы точность ± 500 метров.
Этих эффектов, между прочим, немного больше чем учел товарищ Элбург. Помимо релятивистского эффекта Доплера присутствует также Shapiro Propagation Delay и пр.
И уж совсем смешны умозаключения этого последнего болвана в свете того, что экспериментаторы подстраховались и проверили точность измерений при помощи поистине точнейшей установки с двумя цезиевыми часами немецкого института «мер и весов» www.ptb.de
Результаты совпали с GPS методом, с точностью до 2 нс.
Еще раз простите меня за мой французский.
Вот вам безупречный с точки зрения архитектуры пример реализации MVP паттерна:
www.logicdevelopment.net/blog/?p=16
В идеале библиотека (коих в приложении может быть больше чем одна штука) не навязывает мне использование какой-либо конкретной реализации логирования, а пользуется нейтральным интерфейсом, оставляя выбор реализации за конечным приложением (именно эту возможность дают SLF4J и динозавр commons logging).
И уж совсем печально видеть порой библиотеки, которые не только берут ответственность в выборе реализации логирования на себя, но вдобавок еще и перенимают на себя всю конфигурацию.
Пожалуйста, избегайте подобные фокусы. Помните, каждый раз, когда вы компилируете такой код, где-то умирает маленький котенок.
Назвать хотя-бы Configuration Admin Service и Fragments.
— Нейтрино!
— Кто там?
— Тук тук!
Именно это происходит, если в classpath есть
org.hamcrest:hamcrest-all
иjunit:junit
, т.к. последний уже содержит в себе некоторые hamcrest-классы.Разработчики JUnit советуют вкупе с hamcrest-all использовать исключительно пакет junit:junit-dep, который не содержит в себе hamcrest классов. Maven кофиг выглядит примерно так:
Но тут есть подвох: пакет
junit-dep
имеет compile-scope зависимость от пакетаhamcrest-core
, хотя логичнее был бы provided-scope. Как следствие, в class-path попадают не два, а три пакета:со всеми вытекающими последствиями.
Единственное противоядие от недуга, «выпиливать» ненужный hamcrest-core в ненужной, устаревшей версии. Примерно так:
p.s. мои опасения насчет 4.9 подтвердились.
hamcrest-core
по-прежнему включен в compile-scope пакетаjunit-dep
. Видимо придется писать команде баг-репорт, благо ребята сами вызвались поддерживать maven пакеты…вот, к примеру, betamax (internetcalls) vs gmail-call
Russian Federation (Landline) 2,10 vs 4,00
Russian Federation ( Mobile ) 4,20 vs 6,00
Russian Federation [ moscow ] 0,50 vs 2,00
Russian Federation [st. Pet.] 0,50 vs 2,00
И это при том, что betamax предлагает открытый VOIP протокол, что тоже немаловажно.