Вы достигли нового уровня

Уровень 38

1. Гибкая_методология_разработки

- Привет, Амиго!

- Привет, Билаабо!

- Сегодня я расскажу тебе о том, как обычно разрабатываются программы.

В 20 веке, когда современное ИТ только зарождалось, всем казалось, что программирование чем-то похоже на строительство или производство.

Обычно дело обстояло примерно так:

Заказчик рассказывал, что за программу ему надо, что и как она должна делать.

Бизнес-аналитики выслушивали его и, на основе его историй, составляли полный список требований к программе.

Затем менеджеры проекта разбивали эти требования на задачи (таски), а также определяли, какой программист будет делать какую таску и в каком порядке.

Затем программисты приступали к работе. Иногда это могло занять несколько лет(!).

Когда работа была сделана, программу отдавали тестировщикам.

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

Если что-то было не так, тестировщики писали баги и отправляли их программистам.

Затем программисты фиксили (исправляли) эти баги и опять отправляли исправленную программу тестировщикам. И так по кругу.

Когда основные баги были исправлены, программа отдавалась заказчику.

- Что так прям все и происходило?

- Ну, тут конечно многое упрощено, но дело почти так и было.

- И что, проект реально мог писаться полтора-два года?

- Иногда, когда разработка проекта была очень длительной, ее разбивали на отдельные релизы. Каждый 3-6 месяцев разработчики обязаны были сделать определенную часть функционала программы, протестировать ее, исправить в ней все баги и показать заказчику.

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

- Продолжал платить?

- Тогда разработка очень часто растягивалась в 2-3 раза. А т.к. оплата труда программистов часто была почасовая, то и стоимость программы вырастала в 2-3 раза. А вот польза от нее при этом падала. Ведь то, что нужно сегодня и за $100,000, совсем не обязательно будет нужно через 3 года, да еще за втрое большую цену.

- Т.е. заказчики часто отказывались платить?

- Ага. Потом они придумали добавлять в договора штрафные санкции, но это ситуацию не улучшило. Разработка программ затягивалась и затягивалась? и никто не мог с этим ничего поделать, даже если хотел.

- А почему так?

- Ну, во-первых, на этапе планирования слишком многое не известно. Чаще всего, проблемы, с которыми сталкиваются программисты, в самом начале не мог предсказать никто.

- Но ведь опытные программисты должны были бы сами все предвидеть, разве нет?

- Видишь ли, программирование – это уникальная профессия.

Обычный специалист очень часто выполняет одну и ту же работу. Часовщик делает часы, повар – готовит, учитель – учит, врач – лечит, и т.д.

Каждый из них фактически каждый день занимается тем же самым, что и вчера. И поэтому начинает делать свою работу все лучше и лучше.

В программировании другой подход. Как только у программиста каждый день возникает одна и та же задача, он пишет для нее функцию/модуль/программу и больше к ней не возвращается.

Каждую свою задачу программист, обычно, решает один раз в жизни.

Чем-то похоже на ученого или на инженера-конструктора, который что-то изобретает.

- Ага. А какая роль в проекте самая важная?

- Ну, что тебе сказать. Легко сказать, какая самая важная, сложно сказать – какая самая не важная.

Основная задача тестировщиков (Quality Assurance, QA) – это следить за состоянием работы программы и во время рапортовать об найденных ошибках. Чем больше и раньше тестировщик найдет ошибок, тем больше их будет исправлено. Хороший тестировщик влияет на качество продукта больше, чем хороший программист.

- А почему программист не может сам тестировать свою программу. Ведь он лучше знает, что в ней работает, а что – нет?

- Хороший программист просто не может быть хорошим тестировщиком. Программист хорошо знает, как устроена программа, поэтому пользуется ей всегда специфическим образом. В отличие от пользователя, который пользуется программой, как бог на душу положит.

Кроме того, тестировщик не тестирует то, что еще не работает. Тестировщик тестирует ту функциональность, те части программы, которые по мнению программиста уже работает и работают чуть ли не идеально.

И вот когда тестировщик находит там горы ошибок, а программист их исправляет, продукт действительно становится ближе к идеалу.

Основная задача программиста (Software Developer Engineer, Developer, SDE) – реализовывать новую функциональность. Или, если быть проще – выполнять назначенные на него задачи. Назначили задачи с новыми фичами – делает их. Назначили баги – фиксит баги.

- Что-то у тебя одни англицизмы в разговоре. Каждое второе слово.

- Это не столько англицизмы, сколько профессиональный сленг. Привыкай.

Но иногда бывают задачи и посложнее, например, придумать архитектуру программы или ее части. Чем лучше будет предложенная архитектура, тем легче будет делать дальнейшую работу.

Проблема в том, что архитектуру надо выбрать в самом начале, а удачную ты выбрал архитектуру или нет, становится понятно не раньше середины разработки.

Более того, если архитектура была удачной и программа получилась отличной, то, скорее всего, на ее базе заказчик захочет выпустить новую версию программы.

Это я к чему.

Какую бы версию архитектуры программы ты не выбрал, всегда найдется куча изменений, дополнений, новых фич, которые этой архитектурой не учитываются.

Вот тебе хороший пример.

Заказал заказчик построить дом на 5 этажей, ты придумал архитектуру, и дом построили.

Затем заказчик говорит, а давайте достроим еще один этаж, а затем еще один и т.д.

А ведь стены первых этажей на такую нагрузку не рассчитаны, фундамент тоже, вот и приходится все переделывать.

А если заказчик после дома в 5 этажей захочет дом сразу в 50?

- Тогда легче снести то, что было и построить все заново…

- Но насчет архитектуры, у меня для тебя есть один совет.

Архитектура приложения в первую очередь должна быть гибкой и подразумевать, что при решении переделать половину программы, не придется полностью переделывать вторую половину. Такую архитектуру обычно называют гибкой и модульной.

Основная задача менеджера – это принимать решения. Менеджер – это человек, который видит всю картину и принимает решения исходя из этого.

Допустим, в процессе разработки выяснилось, что некоторая задача не получится в таком виде, в каком ее хотят видеть. И тут менеджер может:

а) попробовать договорится с заказчиком, чтобы эту задачу поменяли

б) выделить больше времени на эту задачу

в) привлечь более опытных программистов с других проектов.

Тут еще много вариантов.

Дело в том, что в каждом из них придется чем-то жертвовать, а задача менеджера – снизить суммарный ущерб от таких жертв к минимуму.

Или, например, ведущего программиста перекупают конкуренты, предложив в два раза больше денег.

Менеджер может:

а) ничего не делать. Программист уходит, проект, вероятно, затянется и попадет на штрафные санкции.

б) поднять ему зарплату в два раза. Тогда остальные люди в команде тоже захотят себе повышения ЗП. Если всем им дать денег, расходы на проект вырастут, и он может стать убыточным.

в) свой вариант.

- Ясно.

- Обычно, когда плохой менеджер, проект может вытянуть хорошая команда, но не всегда.

Хороший менеджер и команда средних программистов почти всегда сделают проект быстрее, чем плохой менеджер и команда отличных программистов.

- Ясно.

- Вот как выглядят эти профессии глазами друг друга:

- Ха-ха, смешно.

- Ладно, давай сделаем небольшой перерыв, а потом – продолжим.

2. Agile, Scrum, waterfall

- И так, я хочу рассказать тебе про Agile и Scrum.

В начале 21 века представление о программировании перевернулось.

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

- Это как же?

- А вот так.

Был придуман максимально гибкий подход к управлению работой.

Основные концепции гибкой разработки:

Принципы быстрой разработки:

Основной проблемой разработки программы было признано то, что никто из участников ни на одном этапе не обладает всей полнотой информации о том, что делать.

Заказчик может рассказать, как он видит программу, но что-то он упускает, что-то считает само-собой разумеющемся.

Менеджер вообще должен переводить требования с языка программистов на язык заказчика и обратно.

Слишком много неопределённости.

Часто требования заказчика выглядят так – сделаете как-нибудь, потом покажите мне, если мне не понравится – переделайте.

- М-да. Как все запущено.

- Согласно новому видению, программисты больше не выпускают продукт или программу, они реализуют нужную заказчику функциональность.

- А в чем разница?

- Ну, смотри, допустим, раньше на разработку программы уходил год. И только через первых полгода было уже на что посмотреть. Это как строить большой дом: сначала котлован, потом фундамент, стены, крыша, отделка и т.д.

А теперь программисты стараются как можно раньше выпустить нужный заказчику функционал. Это как если бы строители сначала построили шалаш, затем времянку, затем небольшой домик, затем уже начали делать большой дом и тот – по частям.

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

Допустим, хочет заказчик большой охотничий домик.

Построили ему маленький, он в нем пожил зиму и решил, что дом из дерева ему не нравится. Будем делать из кирпича в 4 слоя.

Пожил рядом с озером летом, а его комары заели. Он где-то слышал, что озеро – это круто, вот и хотел. А теперь ему озеро не надо. Так ведь и дом строить легче: нет озера – нет угрозы паводков, вот и можно строить дом не на сваях, а на земле, а это на 25% быстрее.

- Интересная аналогия. Неужто, заказчик так часто меняет свои требования?

- Да дело тут не в заказчике.

Во-первых, очень сложно представить наперед – что получится. И менеджеры, и тестировщики, и программисты тоже бывают в такой роли. И тоже меняют свое мнение в зависимости от того, что получилось.

А во-вторых, разве требования заказчика – не главное? Ведь смысл всей этой работы – это сделать именно то, что заказчику нужно, а не то, что он сказал в самом начале делать.

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

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

- Ясно. Работать по плану легче, но не все можно сделать по плану!

- Именно.

Поэтому были придуманы методики гибкой разработки.

И о самой популярно из них – Scrum, я тебе сегодня расскажу.

Основная фишка скрама – это разбитие разработки проекта на небольшие итерации – обычно 2-4 недели. Такая итерация называется «спринт».

Вначале спринта проводится «планирование спринта» - совещание часа на 3-4.

В конце – проводится «демо» - демонстрация всех полностью завершенных задач.

Вот как обычно все происходит:

Перед самым первым спринтом, заказчик (или его представитель), формирует список требований – набор того, что должна уметь программа. Такие требования обычно называют «user story», а заказчика – «product owner».

Product owner переводится как владелец продукта, т.к. продукт пишется для него и он и только он определяет список требований – что надо, когда и в каком порядке.

Кроме того, product owner обычно еще назначает задачам приоритет. Сначала будут реализовываться задачи с самым высоким приоритетом. Весь список требований еще называют «product backlog» или «резерв продукта».

Когда начинается спринт, то все собираются на совещание. Ведет его обычно scrum-master, обычно это кто-то из команды. Цель совещания – отобрать задачи (user story) на текущий спринт (итерацию разработки).

Сначала каждой задаче дается коллективная приблизительная оценка в «абстрактных человеко-днях», их еще называют «story point». Затем команда решает, сколько задач она успеет сделать за этот спринт.

При этом команда сама решает – сколько задач она успеет сделать за спринт.

Допустим, product owner ожидал, что команда отберет 7 первых задач, а она отобрала всего 5, то задачи 6 и 7 переносятся на следующий спринт. Если product owner это не устраивает, он может повысить приоритет 6 и 7 задачи, чтобы их точно отобрали, но тогда из спринта выпадут какие-то другие задачи.

Так же scrum master может предложить разбить часть задач на более мелкие и расставить им различные приоритеты, чтобы product owner оказался максимально довольным.

В этом и есть смысл совещания – задачи можно менять и разбивать, можно менять им приоритеты и т.д. Это именно та работа, которая не была видна в самом начале, но которая приносит очень много пользы.

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

- Да, как-то так.

Список задач отобранных для спринта называют sprint backlog или резерв спринта.

Программисты распределяют, кто и что будет делать, а только затем приступают к работе. Для повышения эффективности, скрам предлагает, чтобы каждый день проводились совещания по 5-15 минут, где все бы рассказывали друг-другу, кто что сделал за прошедший день и чем будет заниматься сегодня.

- Командная работа. Уважаю!

- Для лучшей наглядности, обычно предлагают отображать текущее состояние спринта на специальной доске:

Обрати внимание на три колонки слева.

На стикерах пишутся краткие названия задач. А стикеры переклеиваются в другую колонку в зависимости от статуса (В планах, В процессе, Готово)

Справа ты видишь «диаграмму сгорания». Там по дням отображаются список задач, которые еще остались несделанные. В идеале за время спринта количество неготовых задач падает до нуля.

Когда спринт завершается, scrum-master проводит demo, на котором демонстрируется список всего, что полностью сделано.

Затем проводится «разбор полетов» - совещание тоже на пару часов. На нем обычно пытаются выяснить, что было сделано хорошо, а что (и как) можно было сделать лучше.

Обычно за 2-3 спринта можно выявить основные проблемы, которые мешают команде работать эффективнее, и устранить их. Это приводит к большей продуктивности, не увеличивая нагрузку на команду. Такое было невозможным до эры гибких методологий.

В середине спринта, иногда еще проводят «вычесывание» - совещание посвященное планированию следующего спринта. На нем обычно уточняют приоритеты задач, а так же можно разбить некоторые задачи на части и/или добавить новые задачи в product backlog – резерв продукта.

В принципе у меня все – это обзорная лекция, и на пальцах ее не объяснить, но вот тут ты можешь почитать пару хороших статей на эту тему:

http://scrum.org.ua/wp-content/uploads/2008/12/scrum_xp-from-the-trenches-rus-final.pdf

http://ru.wikipedia.org/wiki/SCRUM

3. иерархия исключений, errors

- Привет, Амиго!

- Привет, Элли! Как жизнь?

- Отлично, спасибо. А ты как?

- Супер, сегодня утром столько всего нового рассказали.

- Так это же отлично. Не устал?

- Да, есть такое дело. Подустал немного.

- Тогда тебе просто повезло. Потому что хотела тебе сегодня дать большую и сложную тему, но в последний момент передумала и решала рассказать маленькую и легкую.

- Маленькую и легкую? Я готов.

- Сегодня мы с тобой детально разберем тему исключений - Exception.

- Ты про обработку ошибок?

- Считать исключение ошибками – это неверный подход. Исключения больше похожи на отчет о том «что пошло не так». На основе которого, можно предложить альтернативные сценарии действия.

Все дело в методах. Когда ты вызываешь какой-то метод, он гарантированно должен сделать то, для чего его вызвали.

Когда метод по каким-либо причинам не может сделать то, для чего его вызвали, он обязан уведомить об этом вызывающего.

Т.е. самое худшее, что может случиться – это когда метод не выполнил свою работу, и никого об этом не уведомил. Хуже этого не может быть ничего. Это потеря контроля над ситуацией.

Когда ты начинающий программист, тебе кажется, что ты вызываешь методы и они обязательно сделают то, о чем ты их просишь.

Когда ты опытный программист, ты знаешь, что могут быть десятки факторов, которые влияют на выполнение методом своей работы, и возможны очень много различных случаев, когда метод не смог выполнить свою работу.

С точки зрения программиста, если в программе произошел сбой, и она закрылась – это в тысячу раз лучшая ситуация, чем, если в программе произошел сбой, она работает неправильно и пользователь об этом не подозревает.

- Как то, что программа что-то показывает неправильно, может быть хуже, чем, если программа закрылась, и все данные потерялись?

- А с чего ты взял, что программа просто что-то неправильно показывает? Может у нее внутри куча ошибок и все данные твоей работы с ней будут безвозвратно потеряны? Ты 3 часа набирал текст, который не сохранится, потому что на второй минуте работы произошла ошибка.

Когда начинающий программист сталкивается с исключениями, он расстраивается.

Но на самом деле, исключения показывают ему все те сценарии поведения, которые он должен был предусмотреть и не предусмотрел.

Ты можешь не обрабатывать исключения и тогда ты плохой программист. Но если твои методы не выкидывают исключений, тогда ты вообще не программист, т.к. так и не понял простой истины:

Метод либо делает то, для чего он написан, либо кидает исключение. Третьего не дано!

- Ладно, верю. Обещаю пользоваться исключениями.

- Отлично. Тогда давай я тебе расскажу про иерархию исключений:

Иерархия исключений базируется на четырех классах.

Самый базовый класс – это Throwable.

От него унаследованы классы Error и Exception.

От Exception унаследован RuntimeException.

Класс Error является базовым классом для ошибок Java-машины, таких как StackOverFlow, OutOfMemory, …

Исправить последствия таких ошибок программа обычно не может и это приводит к ее завершению.

Действительно, что можно сделать, если для дальнейшей нормальной работы программы не хватает памяти или переполнился стек.

Класс Exception является базовым для всех обычных исключений, которые выбрасываются программой. RuntimeException – это подкатегория исключений Exception, к которым применяются немного другие правил.

- Это какие?

- Как раз сейчас и расскажу.

Как ты, наверное, помнишь, исключения делятся на две категории checked (проверяемые) и unchecked (непроверяемые).

Если метод выкидывает checked исключения, то вызывающий его метод, обязан обернуть вызов такого метода в блок try-catch. Ну, или пробросить исключение выше (своему вызывающему), явно указав его в списке throws в сигнатуре метода.

На unchecked такие правила/ограничения не распространяются.

Так вот, все исключения, унаследованные от Exception, считаются checked. Кроме исключений, которые унаследованы от RuntimeException – они unchecked.

- Ага. Вспоминаю, что-то такое мне уже раньше рассказывали.

- Амиго! Иерархию исключений спрашивают на каждом собеседовании. Еще раз – на каждом. Ты должен великолепно знать эту тему.

- Ок. Я еще раз все перечитаю и разберусь. Спасибо, что помогаешь мне, Элли.

4. Задачи

- Привет, Амиго!

- Я найду для тебя новые интересные задачи чуть позже. Если у тебя остались нерешенные задачи, быстрей решай их. Ты уже на финишной прямой.

5. throwable, multiple exceptions, эксепшн внутри метода finalize

- Ага. Вот ты где. Я уже тебя обыскалась.

- Что-то случилось?

- Нет, но мы же занимаемся.

- Ок. Я тебя слушаю.

- Я хочу тебе рассказать об исключениях еще пару фактов:

В Java 7 конструкция try-catch была немного расширена за счет добавления «множественных catch». Смотри пример:

Java 5Java 7
try
{
  …
}
 catch (IOException ex)
{
 logger.log(ex);
 throw ex;
}
 catch (SQLException ex)
{
 logger.log(ex);
 throw ex;
}
try
{
  …
}
 catch (IOException | SQLException ex)
{
 logger.log(ex);
 throw ex;
}

- Т.е. теперь можно писать несколько исключений через ИЛИ ( «|» - это бинарный ИЛИ)?

- Да, правда, удобно?

- Гм. А какой тип будет у этого объекта-исключения внутри блока catch?

Ведь у IOException могут быть свои методы, а у SQLException – свои.

- Тип исключения будет такой же, как и у их общего класса-предка.

- Ага. Т.е. скорее всего Ecxeption или RuntimeException. Почему тогда просто не написать catch(Exception e)?

- Иногда, когда программисты обрабатывают все ошибки отдельно, бывает удобно разбить их на группы и одни ошибки записать в лог, другие пробросить выше, третьи обработать иным способом.

Т.е. такая схема признана решить проблему дублирования catch-блоков кода для обработки разных ошибок.

- Ага. Понято. Спасибо, Элли.

- Это еще не все, я хочу еще рассказать немного про блок finally.

Как ты уже, наверное, знаешь, этот блок выполняется всегда.

Когда я говорю всегда, я имеют ввиду абсолютно всегда.

Пример:

Пример с finally
try
{
 return 1;
}
 finally
{
 return 0;
}

Тут есть return в блоке try и return в блоке finally. Так вот, результатом вызова метода будет число 0.

Блок finally выполнится, чтобы не произошло. А его метод return перезатерт старое возвращаемое значение своим значением.

- Ясно.

Более того, метод может либо вернуть значение, либо выбросить исключение.

Поэтому, если в блоке try возвращается значение, а в finally выбрасывается исключение, то в результате будет исключение.

- А если в блоке try выбрасывается исключение, а в блоке finally выполняется return?

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

ПримерРезультат
try
{
 return 1;
}
 finally
{
 return 0;
}
0
try
{
 return 1;
}
 finally
{
 throw new RuntimeException();
}
RuntimeException
try
{
 throw new RuntimeException();
}
 finally
{
 return 0;
}
0
try
{
 throw new RuntimeException();
}
 finally
{
 throw new IOException();
}
IOException

Единственной причиной, по которой может не выполнится метод finally, может быть немедленное завершение программы, посредством вызова метода System.exit();

Пример
try
{
 System.exit(0);
 return 1;
}
 finally
{
 return 0;
}

- Ясно.

- Учти, обычно на собеседования спрашивают все из этой темы, так что лучше тебе это и понять и запомнить.

6. Задачи

- Привет, Амиго!

- Я найду для тебя новые интересные задачи чуть позже. Если у тебя остались нерешенные задачи, быстрей решай их. Ты уже на финишной прямой.

7. Аннотации. Как пользоваться

- Привет, Амиго!

- Здорово, Риша.

- Сегодня я поглубже познакомлю тебя с аннотациями.

Как ты уже, наверное, знаешь – аннотации – это такие специальные слова, которые можно размещать рядом с классами, полями, методами и переменными.

- Ага. Очень часто их встречаю.

- Иногда их называют еще метаданными. Основная их задача – хранить некоторую дополнительную информацию о методах, полях и классах.

- А для кого они ее хранят?

- Это очень хороший вопрос.

Раз эти аннотации пишут, значит, они кому-то нужны.

Аннотации позволяют хранить дополнительную информацию о коде и элементах программы, но формально не являются частью кода.

Аннотации можно использовать для генерации XML, определения, устарел метод или нет, отслеживания ошибок и т.п.

Пример аннотаций в коде:

Пример
@CatInfo(manager=Catmanager.class, unique=true)
class Cat
{
 @Name("Murka")
 private String name;

 @SuppressWarnings(value = "unchecked")
 void getUniqueCatName()
 {

 }
}

Как ты видишь, в аннотациях можно хранить данные.

Если аннотация имеет только одно поле value, то его можно опускать:

Пример
@SuppressWarnings("unchecked")
void getUniqueCatName()
{

}

Если параметров в скобках нет, скобки тоже можно не писать:

Пример
@Override
void getUniqueCatName()
{

}

Создать свою аннотацию очень легко. Объявление аннотации – практически идентично объявлению интерфейса.

Пример
@interface CatManager
{
 Class manager();
 boolean unique();
 String name() default "Unknown Cat";
}

Есть всего пара отличий.

Во-первых, перед словом interface ставится символ «@».

Во-вторых, аннотация может содержать значения по умолчанию. Для этого используется слово default. См. пример выше. Такие параметры являются необязательными и их можно опускать при добавлении аннотаций.

- Ага. Все оказалось проще, чем я думал. А то я уже шарахался от них, как Рободьявол от святой воды. Неприятно, когда в коде куча всяких штук, которые до конца не понимаешь.

- О, хорошо, что напомнил, хочу еще рассказать об аннотациях, используемых компилятором.

Таких аннотаций всего 3. Пока три.

@Deprecated.

Класс или метод можно пометить аннотацией @Deprecated. Тогда компилятор будет выдавать предупреждение (предупреждение - это не ошибка), а Intellij IDEA будет отображать этот метод как перечеркнутый. Примерно так:

Пример
Date date = new Date();
int year = date.getYear();

@Override.

При переопределении метода, хорошим тоном считается добавить ему аннотацию @Override.

- А для чего? Вроде же IDEA и так показывает, переопределен метод или нет?

- Во-первых, то IDEA, а то синтаксис Java.

А во-вторых, гипотетически может быть ситуация, когда метод базового класса переименуют, а метод наследника – нет. И программа будет работать неправильно, но никто этого не заметит. Для предотвращения таких ситуаций и была придумана эта аннотация:

Пример
@Override
void getUniqueCatName()
{

}

@SuppressWarnings.

- Иногда компилятор выводит очень много предупреждений. Или мы знаем о «проблемах» и сознательно пошли на такое использование. С помощью этой аннотации можно скрыть часть из них.

С помощью аннотации @SuppressWarnings, программист может сказать компилятору: не нужно показывать предупреждения, так задумано, это не ошибка. Пример:

Пример
@SuppressWarnings("unchecked")
void getUniqueCatName()
{

}

- Понятно.

- Что-то я немного устал, пойду, промочу горло. Давай продолжим после перерыва, ок?

- Конечно.

8. Задачи

- Привет, Амиго!

- Я найду для тебя новые интересные задачи чуть позже. Если у тебя остались нерешенные задачи, быстрей решай их. Ты уже на финишной прямой.

9. Аннотации, как создавать

- Так вот, давай-ка сейчас создадим парочку аннотаций и используем их.

Например, мы пишем движок для игры. При этом у нас в игре очень много персонажей, которые делятся на три категории: эльфы, охрана дворца и злодей.

В процессе разработки игры, могут добавляться новые персонажи, и при этом будет меняться баланс игры. Поэтому было бы очень удобно приписать каждому «классу персонажа» свою аннотацию с описанием его физических характеристик.

Тогда можно было бы очень просто симулировать бои между различными персонажами и/или быстро просчитать баланс игры.

- Согласен – это хорошая идея.

- Давай создадим аннотацию @Person, где будем хранить: жизнь, силу, магию, а также параметры атаки и защиты. Вот как бы выглядела такая аннотация:

Пример
@interface Person
{
 String name() default "";
 int live();
 int strength();
 int magic() default 0;
 int attack() default 0;
 int defense();
}

А вот так выглядело бы описание, например, лесного эльфа-мага:

Пример
@Person(live=100, strength=10, magic=5, attack=20, defense=20)
class Elf
{
 …
}

А вот так выглядело бы описание главного злодея:

Пример
@Person(live=1000, strength=150, magic=250, attack=99, defense=99)
class EvilMaster
{
 …
}

- Ясно. Чем-то напоминает интерфейсы-маркеры.

- Да, только, во-первых, не приходится ничего наследовать, во вторых, в аннотациях можно хранить дополнительную информацию.

Есть еще несколько аннотаций, которыми помечаются аннотации. Вот они:

Аннотация @Retention указывает, где будет видна наша аннотация: только в исходном коде, еще и после компиляции, будет доступна даже во время исполнения программы.

Аннотация @Target указывает, что именно можно пометить этой аннотацией: класс, поле, метод, параметр метода и т.д.

Если мы хотим, чтобы наша аннотация действовала не только на отмеченный ей класс, но и на его наследников, то надо пометить ее @Inherited.

Вот как будет выглядеть наша аннотация @Person.

Пример
@Target(value=ElementType.TYPE)
@Retention(value=RetentionPolicy.RUNTIME)

@interface Person
{
 String name() default "";
 int live();
 int strength();
 int magic() default 0;
 int attack() default 0;
 int defence();
}

- Это было очень интересно, спасибо, Риша.

А как работать с этими аннотациями в программе? Как их использовать? Как прочитать их значения?

- Для этого принято использовать Reflection.

Вот как выглядело бы определение того, какой из персонажей сильнее:

Пример
public boolean fight(Class first, Class second)
{
 if (!first.isAnnotationPresent(Person.class))
  throw new RuntimeException("first param is not game person");
 if (!second.isAnnotationPresent(Person.class))
  throw new RuntimeException("second param is not game person");

 Person firstPerson = (Person) first.getAnnotation(Person.class);
 Person secondPerson = (Person) second.getAnnotation(Person.class);

 int firstAttack = firstPerson.attack() * firstPerson.strength() + firstPerson.magic();
 int firstPower = firstPerson.live() * firstPerson.defence() * firstAttack;

 int secondAttack = secondPerson.attack() * secondPerson.strength() + secondPerson.magic();
 int secondPower = secondPerson.live() * secondPerson.defence() * secondAttack;

 return firstPower > secondPower;
}

Вот методы класса, которые нам нужны:

МетодыОписание
isAnnotationPresent(Annotation.class) Проверят, если ли у класса нужная аннотация
getAnnotation(Annotation.class) Возвращает объект-аннотацию, если такая у класса есть.
Annotation[] getAnnotations() Возвращает массив всех аннотаций класса

- Отлично. А я и не думал, что получить аннотацию так просто.

- Ага. Просто вызвал метод getAnnotation у объекта класса, и передал туда нужный тебе тип аннотации.

На этом на сегодня все.

- Спасибо, Риша, это была очень интересная лекция. И теперь я уже не боюсь аннотаций как воды.

10. Задачи

- Привет, Амиго!

- Я найду для тебя новые интересные задачи чуть позже. Если у тебя остались нерешенные задачи, быстрей решай их. Ты уже на финишной прямой.

11. Учимся гуглить

- Привет, Амиго!

Продолжаем наши уроки – учимся гуглить.

Вот тебе несколько заданий:

 Надо найти в Google
1 Иерархия исключений
2 Java 7 исключения
3 Как пользоваться аннотациями
4 Как создать аннотации
5 Что такое Scrum
6 Что такое Agile
7 Что происходит во время спринта в скраме
8 Что такое спринт
9 Как узнать, что спринт закончился
10 Что такое голосование карточками в скраме

12. Профессор дает доп. материал

- Привет, Амиго!

Вот тебе дополнительный материал по теме.

Ссылка на дополнительный материал

13. Хулио

- Привет, Амиго!

- Привет, Хулио.

- Ты не против поиграть в компьютерные игры?

- Хулио, с тобой не интересно играть. Когда я играю против тебя, я постоянно проигрываю.

- То-то же, я настоящий Game Master. Ладно, давай тогда смотреть видео.

Оригинал видео на YouTube

14. Вопросы к собеседованию по этой теме

- Привет, Амиго!

 Вопросы к собеседованиям
1 Что такое Agile?
2 Что такое Scrum?
3 Какие роли Scrum вы знаете?
4 Что такое спринт? Расскажите с подробностями
5 Кто такие QA?
6 Кто такой product owner?
7 Расскажите об иерархии исключений
8 Что делать если JVM выкинула Error?
9 Какие нововведения в области исключений из Java 7 вы знаете?
10 Зачем нужны аннотации? Как ими пользоваться?

15. Большая задача

- Привет, боец!

- Поздравляю тебя с повышением уровня квалификации. Нам нужны отчаянные парни.

- Уверен, у тебя есть еще много нерешенных задач. Самое время решить парочку из них!