Стилистический вопрос: использование пустого пространства - PullRequest
4 голосов
/ 18 июня 2009

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

Я просто никогда не уверен, когда мне следует оставить пустую строку или использовать комментарий в конце строки вместо комментария выше строки. Я предпочитаю комментировать выше моего кода, но иногда кажется странным прерывать поток комментариев из трех слов. Иногда бросать пустую строку до и после блока кода - это все равно, что помещать скачок скорости в другой плавный фрагмент кода. Например, во вложенном цикле, разделяющем блок кода из трех или четырех строк в центре, практически сводится на нет визуальный эффект отступа (я заметил, что браслеты K & R менее подвержены этой проблеме, чем стили Allman / BSD / GNU).

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

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

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

Спасибо!

P.S. Вот метод из кодовой базы, над которой я работал. Не самый лучший, но далеко не самый плохой.

/**  
 * TODO Clean this up a bit.  Nothing glaringly wrong, just a little messy.  
 * Packs all of the Options, correctly ordered, in a CommandThread for executing.  
 */  
public CommandThread[] generateCommands() throws Exception
 {  
  OptionConstants[] notRegular = {OptionConstants.bucket, OptionConstants.fileLocation, OptionConstants.test, OptionConstants.executable, OptionConstants.mountLocation};  
  ArrayList<Option> nonRegularOptions = new ArrayList<Option>();  
  CommandLine cLine = new CommandLine(getValue(OptionConstants.executable));  

  for (OptionConstants constant : notRegular)  
   nonRegularOptions.add(getOption(constant));  

  // --test must be first  
  cLine.addOption(getOption(OptionConstants.test));  

  // and the regular options...  
  Option option;  
  for (OptionBox optionBox : optionBoxes.values())  
   {  
    option = optionBox.getOption();  
    if (!nonRegularOptions.contains(option))  
     cLine.addOption(option);  
   }  

  // bucket and fileLocation must be last  
  cLine.addOption(getOption(OptionConstants.bucket));  
  cLine.addOption(getOption(OptionConstants.fileLocation));  

  // Create, setup and deploy the CommandThread  
  GUIInteractiveCommand command = new GUIInteractiveCommand(cLine, console);  
  command.addComponentsToEnable(enableOnConnect);  
  command.addComponentsToDisable(disableOnConnect);  
  if (!getValue(OptionConstants.mountLocation).equals(""))  
   command.addComponentToEnable(mountButton);  

  // Piggy-back a Thread to start a StatReader if the call succeeds.  
  class PiggyBack extends Command  
   {  
    Configuration config = new Configuration("piggyBack");  
    OptionConstants fileLocation  = OptionConstants.fileLocation;  
    OptionConstants statsFilename = OptionConstants.statsFilename;  
    OptionConstants mountLocation = OptionConstants.mountLocation;  

    PiggyBack()  
     {  
      config.put(OptionConstants.fileLocation, getOption(fileLocation));  
      config.put(OptionConstants.statsFilename, getOption(statsFilename));  
     }  

  @Override  
  public void doPostRunWork()  
   {  
    if (retVal == 0)  
     {  
// TODO move this to the s3fronterSet or mounts or something.  Take advantage of PiggyBack's scope.  
      connected = true;  
      statReader = new StatReader(eventHandler, config);  
      if (getValue(mountLocation).equals(""))  
       {  
        OptionBox optBox = getOptionBox(mountLocation);  
        optBox.getOption().setRequired(true);  
        optBox.requestFocusInWindow();  
       }  

      // UGLY HACK... Send a 'ps aux' to grab the parent PID.  
      setNextLink(new PSCommand(getValue(fileLocation), null));  
      fireNextLink();  
     }  
   }  
 }  

PiggyBack piggyBack = new PiggyBack();  
piggyBack.setConsole(console);  
command.setNextLink(piggyBack);  
return new CommandThread[]{command};  
}  

Ответы [ 13 ]

11 голосов
/ 18 июня 2009

Неважно.

1) Разработайте собственный стиль. Что бы вы ни находили самым простым и удобным, сделайте это. Старайтесь быть настолько последовательными, насколько это возможно, но не становитесь рабом последовательности. Стреляй примерно на 90%.

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

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

5 голосов
/ 18 июня 2009

Нелегко делать красивый код. Когда я пишу что-то, чем я действительно горжусь, я обычно делаю шаг назад, смотрю на весь метод или класс и точно понимаю, что он делает с первого взгляда - даже спустя месяцы. Эстетика играет в этом роль, хотя и не так важна, как хороший дизайн. Кроме того, осознайте, что вы не можете всегда писать симпатичный код (нетипизированный ADO.NET кто-нибудь?), Но когда вы можете, пожалуйста, сделайте.

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

4 голосов
/ 18 июня 2009

Мне нравится разбивать логические «фразы» кода на пробелы. Это помогает другим легко визуализировать логику в методе - или напомнить мне, когда я вернусь и посмотрю на старый код. Например, я предпочитаю

reader.MoveToContent();
if( reader.Name != "Limit" )
    return false;

string type = reader.GetAttribute( "type" );
if( type == null )
    throw new SecureLicenseException( "E_MissingXmlAttribute" );

if( String.Compare( type, GetLimitName(), false ) != 0 )
    throw new SecureLicenseException( "E_LimitValueMismatch", type, "type" );

вместо

reader.MoveToContent();
if( reader.Name != "Limit" )
    return false;
string type = reader.GetAttribute( "type" );
if( type == null )
    throw new SecureLicenseException( "E_MissingXmlAttribute" );
if( String.Compare( type, GetLimitName(), false ) != 0 )
    throw new SecureLicenseException( "E_LimitValueMismatch", type, "type" );

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

Комментарии в кодовой строке

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

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

3 голосов
/ 18 июня 2009

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

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

1 голос
/ 10 ноября 2009

Для C # я говорю «если» - это просто слово, а «если (» - это код - пробел после «если», «для», «попробовать» и т. Д. Вообще не помогает читаемости, поэтому ядумаю, что лучше без пробела.

Также: Visual Studio> Инструменты> Параметры> Текстовый редактор> Все языки> Вкладки> KEEP TABS!

Если вы разработчик программного обеспечения, который настаивает на использованиипробелы, где вкладки принадлежат, я буду настаивать, чтобы вы были неряшливым - но что угодно - в конце концов, все это скомпилировано. С другой стороны, если вы веб-разработчик с кучей последовательных пробелов и других лишних пробелов всеповерх вашего HTML / CSS / JavaScript, вы либо ничего не знаете о коде на стороне клиента, либо просто не дерьмо. Код на стороне клиента не компилируется (и не сжимается с настройками IIS по умолчанию) - бессмысленные пробелы вклиентский скрипт подобен добавлению бессмысленных вызовов Thread.Sleep () в код на стороне сервера.

1 голос
/ 03 июля 2009

Вот как бы я перестроил этот метод. Конечно, все еще можно улучшить, и я еще не проводил рефакторинг класса PiggyBack (я просто перенес его на более высокий уровень).

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

public CommandThread[] buildCommandsForExecution() {
    CommandLine cLine = buildCommandLine();
    CommandThread command = buildCommandThread(cLine);
    initPiggyBack(command);
    return new CommandThread[]{command};
}

private CommandLine buildCommandLine() {
    CommandLine cLine = new CommandLine(getValue(OptionConstants.EXECUTABLE));
    // "--test" must be first, and bucket and file location must be last,
    // because [TODO: enter the reason]
    cLine.addOption(getOption(OptionConstants.TEST));
    for (Option regularOption : getRegularOptions()) {
        cLine.addOption(regularOption);
    }
    cLine.addOption(getOption(OptionConstants.BUCKET));
    cLine.addOption(getOption(OptionConstants.FILE_LOCATION));
    return cLine;
}

private List<Option> getRegularOptions() {
    List<Option> options = getAllOptions();
    options.removeAll(getNonRegularOptions());
    return options;
}

private List<Option> getAllOptions() {
    List<Option> options = new ArrayList<Option>();
    for (OptionBox optionBox : optionBoxes.values()) {
        options.add(optionBox.getOption());
    }
    return options;
}

private List<Option> getNonRegularOptions() {
    OptionConstants[] nonRegular = {
            OptionConstants.BUCKET,
            OptionConstants.FILE_LOCATION,
            OptionConstants.TEST,
            OptionConstants.EXECUTABLE,
            OptionConstants.MOUNT_LOCATION
    };
    List<Option> options = new ArrayList<Option>();
    for (OptionConstants c : nonRegular) {
        options.add(getOption(c));
    }
    return options;
}

private CommandThread buildCommandThread(CommandLine cLine) {
    GUIInteractiveCommand command = new GUIInteractiveCommand(cLine, console);
    command.addComponentsToEnable(enableOnConnect);
    command.addComponentsToDisable(disableOnConnect);
    if (isMountLocationSet()) {
        command.addComponentToEnable(mountButton);
    }
    return command;
}

private boolean isMountLocationSet() {
    String mountLocation = getValue(OptionConstants.MOUNT_LOCATION);
    return !mountLocation.equals("");
}

private void initPiggyBack(CommandThread command) {
    PiggyBack piggyBack = new PiggyBack();
    piggyBack.setConsole(console);
    command.setNextLink(piggyBack);
}
1 голос
/ 03 июля 2009

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

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

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

1 голос
/ 18 июня 2009

Code Complete, Стив Макконнелл (доступно в обычных местах) - моя библия о подобных вещах. У него есть целая глава о макете и стиле, который просто превосходен. Вся книга просто забита полезными и практическими советами.

1 голос
/ 18 июня 2009

Я использую столько же пробелов, сколько и вы :) Пробелы перед методами, перед блоками комментариев. В C, C ++ скобки также предоставляют некоторое «псевдо-пробел», так как в некоторых строках есть только одна открывающая / закрывающая скобка, так что это также помогает разбить плотность кода.

1 голос
/ 18 июня 2009

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

Многие разработчики при запуске проекта заново выбирают стиль, основанный на документе в стиле кодирования ядра Linux. Последнюю версию этого документа можно посмотреть по адресу http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/CodingStyle;h=8bb37237ebd25b19759cc47874c63155406ea28f;hb=HEAD.

Точно так же многие сопровождающие настаивают на том, чтобы вы использовали Checkpatch перед отправкой изменений в систему контроля версий. Вы можете увидеть последнюю версию, которая поставляется с ядром Linux в том же дереве, на которое я ссылался выше, в scripts / checkpatch.pl (я бы дал ссылку на него, но я новичок и могу опубликовать только одну гиперссылку на ответ).

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

...