Как вы думаете, у этой истории будет счастливый конец? Ну, … — может быть 🙂 — есть инструменты, которые могут помочь достичь этого 🙂 — одним из них является FindBugs , поддерживаемый с JSR-305 (аннотации для обнаружения дефектов программного обеспечения).
Давайте посмотрим на контракт API сервиса:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.blogspot.vardlokkur.services; import java.util.List; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import com.blogspot.vardlokkur.entities.domain.Employer; /** * Defines the API contract for the employer service. * * @author Warlock * @since 1.0 */ public interface EmployerService { /** * @param identifier the employer's identifier * @return the employer having specified {@code identifier}, {@code null} if not found */ @CheckForNull Employer withId( @Nonnull Long identifier); /** * @param specification defines which employers should be returned * @return the list of employers matching specification */ @Nonnull List thatAre( @Nonnull Specification specification); } |
Как видите, к сигнатурам метода службы добавлены аннотации, такие как @ Nonnull или @ CheckForNull . Цель их использования состоит в том, чтобы определить требования к параметрам метода (например, параметр identifier не может быть нулевым ), а ожидания для значений, возвращаемых методами (например, результат метода службы, могут быть нулевыми, и вы должны проверить это в своем коде ).
Ну и что? — спросите вы, — должен ли я сам проверить их в коде или доверить коллегам, что они будут использовать руководящие принципы, определенные этими аннотациями? Конечно, нет 🙂 — никому не доверяйте, используйте инструменты, которые проверят предположения API, такие как FindBugs .
Предположим, что у нас есть следующий сервис API:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package com.blogspot.vardlokkur.test; import org.junit.Before; import org.junit.Test; import com.blogspot.vardlokkur.services.EmployerService; import com.blogspot.vardlokkur.services.impl.DefaultEmployerService; /** * Employer service test. * * @author Warlock * @since 1.0 */ public class EmployerServiceTest { private EmployerService employers; @Before public void before() { employers = new DefaultEmployerService(); } @Test public void test01() { Long identifier = null ; employers.withId(identifier); } @Test public void test02() { employers.withId(Long.valueOf(1L)).getBusinessName(); } @Test public void test03() { employers.thatAre( null ); } } |
Давайте попробуем проверить код в соответствии с предположениями API сервиса:
FindBugs проанализирует ваш код и переключится на перспективу FindBugs, показывая потенциальные проблемы:
Null передан для ненулевого параметра |
Возможно разыменование нулевого указателя |
Аналогичным образом, ребята, пишущие служебный код, могут проверить свою работу в соответствии с определенными допущениями API, например. если вы запустите FindBugs для самой ранней версии реализации сервиса:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
package com.blogspot.vardlokkur.services.impl; import java.util.List; import com.blogspot.vardlokkur.entities.domain.Employer; import com.blogspot.vardlokkur.services.EmployerService; import com.blogspot.vardlokkur.services.Specification; /** * Default implementation of {@link EmployerService}. * * @author Warlock * @since 1.0 */ public class DefaultEmployerService implements EmployerService { /** * {@inheritDoc} */ public Employer withId(Long identifier) { return null ; } /** * {@inheritDoc} */ public List thatAre(Specification specification) { return null ; } } |
Следующая ошибка будет найдена:
Как видите, ничто не может спрятаться от FindBugs и его союзника — JSR-305;)
Несколько ссылок на десерт:
- JSR-305: аннотации для обнаружения дефектов программного обеспечения
- JSR 305: серебряная пуля или не пуля вообще?
Справка: FindBugs и JSR-305 от нашего партнера JCG Миха? Ja? Tak в блоге Мысли Чернокнижника