Статьи

Уже достаточно пробелов

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

Без компилятора, сообщающего вам, когда вы ошиблись, трудно применить стандарт. Иногда это приводит к ошибкам и, по иронии судьбы, к трудному для понимания коду. Может быть, пришло время понять, что форматирование кода отличается от его семантики . Может быть, в 21 веке программисты должны использовать больше, чем просто текстовый редактор?

Нет пробелов

Например, следующее является абсолютно допустимой Java:

01
02
03
04
05
06
07
08
09
10
11
12
13
public String shareWishList() {
 
    User user = sessionProcessor.getUser();  WishList wishList =
 
    loadWishList.forUserByName(user, selectedWishListName); for(
 
    String friend : friends)  { if ( !friend.equals("") )  { new
 
    ShareWishListMail(  friend,  user,  wishList,  emailFactory,
 
    this.serverHostName ) . send();   }   }   return  "success";
 
}

Но большинство нормальных людей предпочли бы, чтобы это было написано «традиционным» способом с разрывами строк в соответствующих местах и ​​разумным использованием символа пробела:

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
public String shareWishList() {
 
    User user = sessionProcessor.getUser();
 
    WishList wishList = loadWishList.forUserByName(user,
 
                            selectedWishListName);
 
    for (String friend : friends) {
 
        if (!friend.equals("") ) {
 
            new ShareWishListMail(friend, user, wishList,
 
                                  emailFactory,
 
                                  this.serverHostName)
 
                .send();
 
        }
 
    }
 
    return "success";
 
}

Строители

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

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

1
2
3
4
5
6
7
8
9
Trade trade = tradeBuilder.addFund(theFund).addAsset(someAsset).atSharePrice(2)
 
    .forShareCount(10).withAmount(20).tradingOn(someDate)
 
    .effectiveOn(someOtherDate)
 
    .withComment("This is a test trade").forUser(myUser)
 
    .withStatus(ACTIVE).build();

Это примерно в миллиард раз легче читать как:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Trade trade =
 
    tradeBuilder.addFund(theFund)
 
                .addAsset(someAsset)
 
                .atSharePrice(2)
 
                .forShareCount(10)
 
                .withAmount(20)
 
                .tradingOn(someDate)
 
                .effectiveOn(someOtherDate)
 
                .withComment("This is a test trade")
 
                .forUser(myUser)
 
                .withStatus(ACTIVE)
 
                .build();

Испытательная установка

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

01
02
03
04
05
06
07
08
09
10
11
12
13
var sharePosition = CreateAnnualSharePosition
 
    .InAsset(someAsset)
 
    .Quarter1Shares(0)        .WithQ1Price(1.250, GBP)
 
    .Quarter2Shares(10000)    .WithQ2Price(1.15,  GBP)
 
    .Quarter3Shares(1000000)  .WithQ3Price(1.35,  GBP)
 
    .Quarter4Shares(1000000)  .WithQ4Price(1.45,  GBP)
 
    .Build();

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

Внутренний DSL

По сути, эти строители являются формой внутреннего DSL . Вы (ab) используете исходный язык для предоставления языка, специфичного для домена, чтобы вы могли описать, что вы на самом деле хотите сделать . Моя предыдущая компания использовала BDD-фреймворк на основе Java — Narrative . Это приводит к очень беглым приемочным испытаниям, но множеству цепочек методов. Как и в случае с шаблоном построения, это было бы совершенно нечитаемо без свободного использования пробелов. Возьмите этот не очень необычный пример:

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
Then.the(user)
 
    .expects_that(the_orders(),
 
         Contains.only
 
         (an_order()
 
                  .of_type(SELL)
 
                  .for_asset(someAsset)
 
                  .for_amount(150, gbp())
 
                  .with_trades(
 
                      allOf(
 
                          Contains.inAnyOrder(
 
                              a_trade_selling("Sub asset 1"),
 
                              a_trade_selling("Sub asset 2")),
 
                          trades_totalling("150")
 
                      ))));

Теперь есть очень специфический «стиль» того, как это изложено. Кто бы ни думал, что это выглядело чистым и читабельным (вероятно, я), явно был в тот день. Но трудно сформулировать подобное «предложение» из-за огромного количества вложений, присущих тому, что он говорит.
Как мы можем определить правила для пробелов, чтобы расположить такие операторы в понятном, читаемом, машиноисполняемом виде? После нескольких месяцев наблюдения за тем, как разные люди проводят бесконечные часы, настраивая пустое пространство под свои личные предпочтения, вы знаете, что я понимаю? Вы не можете автоматизировать это.
Так может мы пытаемся решить не ту проблему? Является ли тот факт, что мы настолько зависим от пробелов, чтобы код не выглядел как полное дерьмо, намек на то, что, возможно, наш текстовый редактор не дает нам выразительную силу, в которой мы нуждаемся? Может быть, просто может быть, в 21 веке программисты могли бы использовать что-то более богатое, чем текстовый редактор? Может быть, в нашем исходном коде есть структура, которую мы могли бы показать лучше?

Строители — Пересмотрено

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

Торговый строитель

Шок! Фильм ужасов! Представь это! Исходный код — это не просто старый текст, а OMG — таблица. Человечность этого! Sacrilege! Предоставление программистам мощного, выразительного, насыщенного текста вместо глупого старого текстового редактора.
Моему основателю позиции акций еще больше помогает выражение в таблице:

долевой строитель

Но как насчет сложного набора вложенных сопоставителей?

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

Но … как это будет работать?

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

Будет ли это работать?

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

Ссылка: Достаточно свободного места уже от нашего партнера JCG Дэвида Грина в блоге Actively Lazy

Статьи по Теме :