Главная страница
Навигация по странице:

  • Предотвращение использования необычных или способствующих ошибкам конструкций

  • Практическая целесообразность уступок

  • Предотвращение опасностей

  • Отражение передовых практик

  • КЕЙС: ВНЕДРЕНИЕ STD::UNIQUE_PTR

  • Обеспечение единообразия

  • КЕЙС: ОФОРМЛЕНИЕ ИМЕН С ИСПОЛЬЗОВАНИЕМ ВЕРБЛЮЖЬЕГО РЕГИСТРА

  • Делай как вGoogle


    Скачать 5.77 Mb.
    НазваниеДелай как вGoogle
    Дата31.05.2022
    Размер5.77 Mb.
    Формат файлаpdf
    Имя файлаDelay_kak_v_Google_Razrabotka_programmnogo_obespechenia_2021_Tom.pdf
    ТипДокументы
    #559735
    страница19 из 69
    1   ...   15   16   17   18   19   20   21   22   ...   69
    155
    происходящего за границами небольшого проекта. Но как только время и воз- можность масштабирования приобретут для проекта большее значение, возрастет вероятность, что его код будет пересекаться с внешними проектами или выйдет за пределы компании. Тогда соблюдение общепринятых стандартов с лихвой окупится в долгосрочной перспективе.
    КОЛИЧЕСТВО ПРОБЕЛОВ
    Руководство по стилю для Python в Google изначально обязывало использовать в коде на
    Python отступы с двумя пробелами. Стандартное руководство по стилю для Python, ис- пользуемое внешним сообществом, предлагает оформлять отступы четырьмя пробелами.
    Большая часть кода на Python, написанного нами раньше, была направлена на непосред- ственную поддержку наших проектов на C++, а не на создание действующих приложений на Python. Поэтому мы решили использовать отступы с двумя пробелами, в соответствии с правилами оформления кода на C++. Шло время, и мы увидели, что это решение не оправдало ожиданий. Инженеры, использующие Python, гораздо чаще читают и пишут код на Python, а не на C++, и им нужно прикладывать дополнительные усилия, чтобы что-то найти или задействовать фрагменты внешнего кода. Мы также сталкивались с большими трудностями каждый раз, когда пытались экспортировать части нашего кода в открытый исходный код, тратя время на согласование различий между нашим внутренним кодом и внешними проектами, к которым мы хотели присоединиться.
    Когда пришло время создать для Starlark (
    https://oreil.ly/o7aY9
    ) — языка на основе Python, разработанного в Google для описания процессов сборки — руководство по стилю, мы про- писали использование отступов с четырьмя пробелами, чтобы обеспечить единообразие с внешними правилами
    1
    Предотвращение использования необычных или способствующих
    ошибкам конструкций
    Наши руководства по стилю ограничивают использование некоторых самых не- обычных или сложных конструкций, содержащих малозаметные ловушки. Приме- нение этих конструкций без глубокого понимания всей их сложности легко может приводить к ошибкам. Даже если конструкции понятны действующим инженерам, будущие участники проекта и специалисты, занимающиеся сопровождением кода, могут не иметь такого же понимания.
    Так, правило в руководстве по стилю для Python запрещает использование функций рефлексии (
    https://oreil.ly/ooqIr
    ), поскольку такие функции, как hasattr()
    и getattr()
    , дают пользователю возможность обращаться к атрибутам объектов, используя строковые имена:
    if hasattr(my_object, 'foo'):
    some_var = getattr(my_object, 'foo')
    1
    Стиль форматирования для файлов BUILD, реализованных на Starlark, используется ин- струментом сборки buildifier (
    https://oreil.ly/iGMoM
    ).

    156
    Глава 8. Правила и руководства по стилю
    Казалось бы, в этом примере все в порядке. Но взгляните на следующий фрагмент:
    some_file.py:
    A_CONSTANT = [
    'foo',
    'bar',
    'baz',
    ]
    other_file.py:
    values = []
    for field in some_file.A_CONSTANT:
    values.append(getattr(my_object, field))
    При беглом просмотре не сразу видно, что здесь происходит обращение к полям foo
    , bar и baz
    . В коде нет четких этому подтверждений. Вам придется приложить определенные усилия, чтобы выяснить, какие строки используются для доступа к атрибутам вашего объекта. А что, если вместо
    A_CONSTANT
    код будет читать поля из ответа, полученного от механизма RPC, или из хранилища данных? Такой запутанный код может проделать незаметную брешь в системе безопасности из-за неправильной проверки сообщения. Кроме того, такой код сложно тестировать и проверять.
    Динамическая природа Python допускает такое поведение и разрешает использовать hasattr()
    и getattr()
    в очень ограниченных случаях.
    Такие возможности языка помогают решать задачи эксперту, знакомому с ними, но часто они слишком сложны для понимания и довольно редко используются инже- нерами. Нам нужно, чтобы с базой кода работали не только эксперты, но и начинаю- щие программисты. Наши инженеры по надежности находят подозрительные места в коде, даже написанном на языке, которым они владеют недостаточно свободно. Мы придаем большое значение интерпретации кода.
    Практическая целесообразность уступок
    По словам Ральфа Уолдо Эмерсона, «глупая последовательность — суеверие неда- леких умов» (
    https://oreil.ly/bRFg2
    ). В нашем стремлении к единообразию и простоте кодовой базы мы не стараемся слепо игнорировать все остальное. Мы знаем, что не- которые правила в наших руководствах по стилю будут сталкиваться с ситуациями, требующими исключений, и это нормально. При необходимости мы отклоняемся от правил в угоду эффективности и практической целесообразности.
    Производительность имеет значение. Иногда есть смысл принять меры по оптимиза- ции производительности даже в ущерб единообразию и удобочитаемости. Например, наше руководство для C++ запрещает использование исключений, но разрешает применение noexcept
    (
    https://oreil.ly/EAgN-
    ) — спецификатора языка, связанного с ис- ключениями, который может включать оптимизацию компилятора.
    Совместимость тоже имеет значение. Код, предназначенный для взаимодействия с чем-то, разработанным за пределами Google, нужно адаптировать для этой цели.

    Создание правил
    157
    Например, наше руководство для C++ содержит исключение из общего правила по оформлению имен с использованием ВерюблюжьегоРегистра, которое разрешает использование змеиного_регистра, как в стандартной библиотеке, для именования сущностей, имитирующих особенности стандартной библиотеки
    1
    . Руководство для
    C++ также допускает несоблюдение некоторых правил при программировании для
    Windows (
    https://oreil.ly/xCrwV
    ), где совместимость с платформой требует использо- вания множественного наследования, которое явно запрещено для всего остального кода на C++ в Google. В наших руководствах по стилю для Java и JavaScript прямо указано, что сгенерированный код, который часто взаимодействует с компонентами, не принадлежащими проекту, или зависит от них, не обязан подчиняться правилам руководств
    2
    . Единообразие является жизненно важным, а адаптация имеет ключевое значение.
    Руководство по стилю
    Итак, какие правила входят в руководство по стилю языка? Все они делятся при- мерно на три категории:
    y правила, предотвращающие опасности;
    y правила, отражающие передовые практики;
    y правила, обеспечивающие единообразие.
    Предотвращение опасностей
    Прежде всего наши руководства по стилю включают правила об особенностях языка, которые должны или не должны использоваться по техническим причинам. У нас есть правила использования статических членов, переменных, лямбда-выражений, исключений, потоков выполнения, прав доступа и наследования классов. В своих правилах мы определяем, какие особенности языка (например, стандартные типы) можно использовать, а какие следует применять с осторожностью, чтобы избежать появления малозаметных ошибок. В описании каждого правила мы стремимся объ- яснить плюсы и минусы принятого нами решения. Большинство из этих решений основаны на необходимости обеспечить надежность кода с течением времени, а также поощрить поддерживаемые приемы использования языка.
    Отражение передовых практик
    Наши руководства по стилю также включают правила применения некоторых передо- вых практик программирования. Эти правила помогают поддерживать работоспособ-
    1
    См. раздел «Exceptions to Naming Rules» (
    https://oreil.ly/AiTjH
    ). Например, наши библиотеки
    Abseil с открытым исходным кодом используют змеиный_регистр для именования типов, предназначенных для использования вместо стандартных типов. См. определения типов в https://github.com/abseil/abseil-cpp/blob/master/absl/utility/utility.h
    . Это C++11-реализации типов из стандарта C++14, для именования которых использован змеиный_регистр вместо более предпочтительного в Google ВерблюжьегоРегистра.
    2
    См. раздел «Generated code: mostly exempt» (
    https://oreil.ly/rGmA2
    ).

    158
    Глава 8. Правила и руководства по стилю ность кодовой базы и простоту ее сопровождения. Например, мы указываем, где и как авторы должны включать комментарии
    1
    . Наши правила, касающиеся комментариев, охватывают общие соглашения о комментировании и определяют конкретные случаи обязательного включения комментариев в код — случаи, когда намерение автора не очевидно, такие как провалы через операторы case в инструкции switch
    , пустые блоки перехвата исключений и метапрограммирование шаблонов. У нас также есть правила, определяющие структуру исходных файлов и описывающие организацию их содержимого. У нас есть правила именования пакетов, классов, функций и пере- менных. Цель всех этих правил — подталкивать инженеров к использованию практик, помогающих писать более здоровый и устойчивый код.
    Некоторые из передовых практик, предписываемых нашими руководствами по стилю, призваны сделать исходный код более удобочитаемым, например через правила форматирования. Наши руководства по стилю указывают, когда и как использовать отступы и пустые строки, определяют длину строк и выравнивание скобок. Требования к форматированию для некоторых языков мы реализовали в инструментах автоматического форматирования: gofmt для Go и dartfmt для
    Dart. Указывая подробный список требований к форматированию или называя инструмент, который необходимо использовать, мы преследуем одну и ту же цель: применить ко всему коду единообразный набор правил форматирования для улуч- шения его читабельности.
    КЕЙС: ВНЕДРЕНИЕ STD::UNIQUE_PTR
    Когда в C++11 появился std::unique_ptr
    — тип «умного» указателя, выражающий ис- ключительное владение динамически размещаемым объектом и удаляющий объект, когда указатель unique_ptr выходит из области видимости, — наше руководство по стилю изна- чально запретило его использовать. Поведение unique_ptr и связанная с ним семантика перемещения были не знакомы большинству инженеров. Предотвращение попадания std::unique_ptr в кодовую базу казалось нам более безопасным выбором. Мы обновили наши инструменты, чтобы находить ссылки на запрещенный тип, и сохранили в существу- ющем руководстве рекомендацию использовать другие типы «умных» указателей.
    Время шло. Инженеры постепенно осваивали семантику перемещения, и мы все больше убеждались, что использование std::unique_ptr прямо соответствует целям нашего руко- водства по стилю. Информация о владении объектом, которую сообщает std::unique_ptr в точке вызова функции, значительно упрощает чтение кода. Дополнительная сложность, связанная с этим новым типом и сопровождающей его семантикой перемещения, все еще вызывала серьезную обеспокоенность, но возможность значительно улучшить общее состояние кодовой базы в долгосрочной перспективе решила компромисс в пользу при- менения std::unique_ptr.
    1
    Основные правила комментирования для нескольких языков см. в https://google.github.io/
    styleguide/cppguide.html#Comments
    , http://google.github.io/styleguide/pyguide#38-comments- and-docstrings и https://google.github.io/styleguide/javaguide.html#s7-javadoc

    Изменение правил
    159
    Наши руководства по стилю также включают ограничения на использование новых и малопонятных особенностей языка, чтобы установить защитные ограждения во- круг потенциальных ловушек, пока сотрудники не пройдут обучение. Сразу после появления новых особенностей языка мы не всегда уверены в том, что правильно понимаем, как их использовать. По мере их изучения инженеры запрашивают у вла- дельцев руководств по стилю разрешение на их использование. Наблюдая за посту- пающими запросами, мы получаем представление об особенностях использования новых возможностей и набираем достаточно примеров, чтобы обобщить хорошие практики, отделить их от плохих и, наконец, внести изменения в правила.
    Обеспечение единообразия
    Наши руководства по стилю также содержат правила, охватывающие множество мелких аспектов. Цель этих правил — просто принять и задокументировать решения.
    Многие правила в этой категории не оказывают существенного влияния на код. Такие правила, как соглашения об именовании, оформлении отступов и порядке инструкций импорта, обычно не дают четкого и измеримого преимущества одной формы перед дру- гой, что может быть причиной продолжения обсуждения разных вариантов в сообще- стве
    1
    . Приняв решение, мы останавливаем бесконечный цикл обсуждений и продолжа- ем двигаться дальше. Наши инженеры больше не выбирают, что лучше — два пробела или четыре. В этой категории правил важен не конкретный выбор, а сам факт выбора.
    И все остальное
    При этом в наших руководствах по стилю многое отсутствует. Мы стараемся сосре- доточиться на том, что оказывает наибольшее влияние на здоровье кодовой базы.
    Существуют намного лучшие практики, не указанные в этих документах, в том чис- ле фундаментальные советы: не умничайте, избегайте ветвления кодовой базы, не изобретайте велосипед и т. д. Такие документы, как наши руководства по стилю, не могут помочь новичку полностью овладеть мастерством программирования — есть некоторые вещи, которые мы подразумеваем и делаем это намеренно.
    Изменение правил
    Наши руководства по стилю не статичны. С течением времени ситуация и факторы, повлиявшие на установление правила, могут измениться. Причиной обновления правила может стать выход новой версии языка. Если правило заставляет инже- неров прикладывать усилия, чтобы обойти его, а инструменты, используемые для соблюдения правила, становятся чрезмерно сложными и обременительными для поддержки, значит, правило потеряло актуальность. Определение момента, когда правило следует пересмотреть, является важной частью процесса сохранения акту- альности и релевантности набора правил.
    1
    Такие дискуссии лишь отвлекают внимание (
    http://aquamarine.bikeshed.com
    ) и иллюстрируют закон тривиальности Паркинсона (
    https://oreil.ly/L-K8F
    ).

    160
    Глава 8. Правила и руководства по стилю
    Решения, лежащие в основе правил в наших руководствах по стилю, подкреплены обоснованиями. Добавляя правила, мы тратим время на обсуждение и анализ его плюсов, минусов и потенциальных последствий, пытаясь убедиться, что данное из- менение подходит для Google, и включаем эти соображения в большинство статей руководств по стилю.
    Документирование обоснования того или иного решения дает нам преимущество: позволяет понять, когда что-то должно измениться. С течением времени и измене- нием условий хорошее решение, принятое ранее, может оказаться не лучшим. Имея перечень четко обозначенных факторов, мы можем определить, когда изменения, связанные с одним или несколькими из этих факторов, требуют переоценки правила.
    КЕЙС: ОФОРМЛЕНИЕ ИМЕН С ИСПОЛЬЗОВАНИЕМ ВЕРБЛЮЖЬЕГО РЕГИСТРА
    Когда мы в Google выпустили начальный вариант руководства по стилю для Python, мы решили использовать для имен методов ВерблюжийРегистр вместо змеиного_регистра.
    В руководстве по стилю для Python (PEP 8, https://oreil.ly/Z9AA7
    ) и в большей части со- общества Python использовался змеиный_регист, однако в ту пору в Google язык Python использовался в основном разработчиками на C++ для создания сценариев, действующих поверх кодовой базы на C++. Многие из определяемых ими типов на Python были оберт- ками для соответствующих типов на C++, а поскольку соглашения об именовании для
    C++, принятые в Google, отдают предпочтение ВерблюжьемуРегистру, считалось важным сохранить единообразие между языками.
    Позднее мы подошли к созданию и поддержке независимых приложений на Python силами инженеров, работающих на Python, а не инженеров C++, пишущих короткие сценарии. Наше руководство по стилю создавало некоторые неудобства и проблемы с удобочитаемостью для инженеров Python, требуя придерживаться единого стандарта для нашего внутреннего кода, из-за чего инженеры были вынуждены постоянно корректировать код под другой стандарт, когда им приходилось использовать внешний код. Руководство также затрудня- ло обучение новых сотрудников, уже имеющих опыт программирования на Python, и их адаптацию к нашим нормам оформления кодовой базы.
    С развитием наших проектов на Python наш код все чаще взаимодействовал с внешними проектами на Python. В некоторых проектах мы использовали сторонние библиотеки, что привело к смешению в кодовой базе нашего ВерблюжьегоРегистра с внешним зме- иным_регистром. Когда мы начали открывать исходный код наших проектов на Python, необходимость их поддержки во внешнем мире, где наши соглашения считались нонкон- формистскими, добавило сложностей для нас и вызвало настороженность сообщества, которому наш стиль показался непривычным и странным.
    Учитывая эти аргументы и после обсуждения отрицательных (потеря единообразия с другим кодом в Google, переобучение гуглеров, использующих наш стиль на Python) и положительных (достижение единообразия с внешним кодом на Python, позволяющим беспрепятственно использовать сторонние библиотеки) сторон, арбитры руководства по стилю для Python решили изменить правило. В результате руководство по стилю для
    Python в Google было обновлено и разрешило использовать змеиный_регистр в именах, но с оговорками: этот стиль должен единообразно применяться во всем файле, разрешение не распространяется на существующий код и команды сами могут решать, какой стиль лучше для конкретного проекта.

    Изменение правил
    161
    Процесс обновления правил
    Понимая, что правила должны периодически изменяться, а также учитывая наше стремление к увеличению срока службы кода и масштабированию, мы определи- ли процесс обновления наших правил. Процесс изменения руководства по стилю основан на решениях. Мы оформляем предложения по обновлению руководства, идентифицируя существующую проблему и представляя предлагаемое изменение как способ ее устранения. «Проблемы» в этом процессе не являются гипотетиче- скими примерами того, что может пойти не так, — они подтверждены паттернами, найденными в существующем коде Google. Рассматривая продемонстрированную проблему и имея подробное обоснование существующего решения по стилю, мы можем пересмотреть его, исследовав оправданность другого решения.
    Сообщество инженеров, пишущих код в соответствии с руководством по стилю, часто раньше других замечает необходимость изменить то или иное правило. Но боль- шинство изменений в руководствах Google начинаются с обсуждения в сообществе.
    Любой инженер может задать вопрос или предложить изменение в списках рассылки по конкретным языкам, посвященным обсуждениям руководств.
    Предложения по изменению руководства могут быть полностью сформированными и включать конкретные формулировки или начинаться с вопросов о применимости существующего правила. Поступающие идеи обсуждаются сообществом и получают отзывы от других пользователей языка. Некоторые предложения отклоняются со- обществом: признаются ненужными, слишком двусмысленными или бесполезными.
    Другие получают положительные отзывы, оцениваются как заслуживающие внима- ния и, возможно, обрастают уточнениями. Предложения, прошедшие обсуждение в сообществе, принимаются для выработки окончательного решения об изменении правила.
    1   ...   15   16   17   18   19   20   21   22   ...   69


    написать администратору сайта