Чистый код. Создание, анализ и рефакторинг (Мартин) - страница 66

Вертикальное разделение концепций

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

Для примера возьмем листинг 5.1. Объявление пакета, директива(-ы) импорта и все функции разделяются пустыми строками. Это чрезвычайно простое правило оказывает глубокое воздействие на визуальную структуру кода. Каждая пустая строка становится зрительной подсказкой, указывающей на начало новой самостоятельной концепции. В ходе просмотра листинга ваш взгляд привлекает первая строка, следующая за пустой строкой.


Листинг 5.1. BoldWidget.java

>package fitnesse.wikitext.widgets;


>import java.util.regex.*;


>public class BoldWidget extends ParentWidget {

>  public static final String REGEXP = "'''.+?'''";

>  private static final Pattern pattern = Pattern.compile("'''(.+?)'''",

>    Pattern.MULTILINE + Pattern.DOTALL

>  };


>  public BoldWidget(ParentWidget parent, String text) throws Exception {

>    super(parent);

>    Matcher match = pattern.matcher(text);

>    match.find();

>    addChildWidgets(match.group(1));

>  }


Листинг 5.1 (продолжение)

>  public String render() throws Exception {

>    StringBuffer html = new StringBuffer("");

>    html.append(childHtml()).append("");

>    return html.toString();

>  }

>}

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


Листинг 5.2. BoldWidget.java

>package fitnesse.wikitext.widgets;

>import java.util.regex.*;

>public class BoldWidget extends ParentWidget {

>  public static final String REGEXP = "'''.+?'''";

>  private static final Pattern pattern = Pattern.compile("'''(.+?)'''",

>    Pattern.MULTILINE + Pattern.DOTALL);

>  public BoldWidget(ParentWidget parent, String text) throws Exception {

>    super(parent);

>    Matcher match = pattern.matcher(text);

>    match.find();

>    addChildWidgets(match.group(1));}

>  public String render() throws Exception {

>    StringBuffer html = new StringBuffer("");

>    html.append(childHtml()).append("");

>    return html.toString();

>  }

>}

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

Вертикальное сжатие

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