1 of 5

Антипаттерны

  • Magic numbers
  • Magic strings
  • Loop-switch sequence

2 of 5

Magic numbers

int someVar = 42; // Somehow it works. Do not touch!

Магическое число (magic number) - числовой литерал, появляющийся в коде без объяснений. При широкомасштабном присутствии создает проблемы:

  • сложность чтения и понимания кода
  • сложность поддержки

Стандартное решение - замена литералов именованными константами.

Не считаются магическими константы, смысл которых очевиден - например, 0 в объявлении цикла for.

3 of 5

Magic strings

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

Стандартное решение - замена отдельных литералов на именованные константы, наборов литералов - на более подходящие типы (например, перечисления).

4 of 5

Loop-switch sequence

Loop-switch sequence - антипаттерн, представляющий фиксированную последовательность действий в виде “оператор switch внутри цикла”. Является формой

  • Появление switch внутри цикла является антипаттерном только в том случае, если на каждой итерации цикла выбор ветви известен на этапе компиляции

Пример кода, реализующего антипаттерн:

// parse a key, a value, then three parameters �String key;�String value;�List<String> params = new List<String>();� �for (int i = 0; i < 5; i++) {� switch (i) {� case 0:� key = stream.parse(); break;� case 1:� value = stream.parse(); break;� default:� params.add(stream.parse()); break;� }�}

Эквивалентный код�// parse a key and value�String key = stream.parse();�String value = stream.parse();� �// parse 3 parameters�List<String> params = new List<String>();

�for (int i = 0; i < 3; i++) {

params.add(stream.parse());�}

5 of 5

Для большей очевидности можно переписать содержимое цикла следующим образом:

int i = 0;

if (i == 0) {

key = stream.parse();

} else {

if (i == 1) {

value = stream.parse();

}

else {

params.add(stream.parse());

}

}

i = 1;

// <...>

Очевидно, что реализация антипаттерна приводит к ухудшению читаемости участка кода (в некоторых случаях [неоптимизирующий компилятор?] это может также повлиять на производительность. С этой точки зрения антипаттерн можно рассматривать в качестве способа обфускации кода. :)