Стили кодирования при использовании нескольких разнородных библиотек

9

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

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

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

Карл Билефельдт
источник
4
Можно ли избежать этой проблемы, обернув все библиотеки в свои собственные абстракции? Ваш собственный код и абстракции могут затем следовать единому стилю кодирования.
MetaFight
Многое из того, что я делаю, это абстрагирование этих библиотек. Вопрос в том, какой стиль кодирования использовать внутри абстракции.
Карл Билефельдт
6
Ах. Я здесь не эксперт, но, похоже, вам лучше использовать соглашение самой библиотеки. Использование несоответствующего соглашения звучит как кошмар обслуживания. И пока стиль библиотеки содержится в классе / модуле, который его абстрагирует, я предполагаю, что все будет в порядке. Опять же, я здесь не профессионал, но это похоже на хороший баланс, который упрощает обслуживание ваших абстракций, а также позволяет вам иметь собственный стиль в остальной части приложения.
MetaFight
1
Иногда подобные абстракции могут быть немного уродливыми, старайтесь поддерживать их в чистоте независимо от используемых соглашений, но, прежде всего, просто убедитесь, что API, который вы представляете из абстракции, имеет достаточное качество, чтобы вам не нужно было возвращаться вмешательство в абстракцию, и потребители смогут легко работать с вашими абстракциями, чтобы их код не превратился в беспорядок, как в ваших абстракциях. Короче говоря, нет хорошего ответа, но до тех пор, пока ваши абстракции представляют хорошие API, по крайней мере, вы не дадите распространиться этой проблеме.
Джимми Хоффа
1
Что именно вы подразумеваете под «стилем кодирования» - простые вещи, такие как использование_underscores / camelCase / PascalCase и расположение фигурных скобок, или более сложные вещи, такие как макет класса / метода / функции и императивный / функциональный стиль?
Изката

Ответы:

10

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

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

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

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

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


Некоторые из выбросов, которые могут изменить мои рассуждения сверху:

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

  • Если все стили достаточно близки друг к другу, было бы так же просто объявить «вот новый путь» и использовать его для всего нового кода и значительных рефакторингов. Это может сделать отзывы немного болезненными, но, по моему опыту, большинство людей вполне способны адаптироваться к этому подходу. Он также предоставляет контрольный знак, где находится старый код.

  • Иногда стиль меняется в зависимости от новой функциональности, добавленной в язык. C ++ приобрел ряд особенностей за эти годы. Возможно, имеет смысл реорганизовать по мере необходимости старый стиль в более новый, использующий эти функции.

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


В некоторых комментариях упоминаются императивные и объектно-ориентированные стили.

Модули, которые являются "тяжелыми" в определенном стиле, вероятно, должны остаться такими, если модуль среднего размера или больше. Я работал с тремя основными стилями (императивный, целевой и функциональный), и я преобразовал тяжелые императивные стили в стиль ОО. При среднем или большем количестве кода рефакторинг может быть (исключительно) сложным. Мой опыт был сбит с толку, потому что у меня не было никакой инструментальной поддержки, чтобы помочь в рефакторинге.

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

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


источник
Это хороший способ выразить это. Подобные проекты около 300 KLOC.
Карл Билефельдт
3

Похоже, есть несколько слоев, чтобы рассмотреть, по крайней мере:

  1. Существующие библиотеки и любые модификации к ним.
  2. Новый код модульного теста для этих библиотек.
  3. Слой абстракции.
  4. API представлен уровнем абстракции.
  5. Пример и тестовый код с использованием уровня абстракции.

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

Принимая в каждом по очереди:

  1. Для существующей кодовой базы вы, вероятно, захотите придерживаться этого стиля.
  2. Новый код модульного теста для существующего кода находится в серой области, особенно в зависимости от того, насколько он интегрирован со старым кодом. Но, скорее всего, я бы попытался сделать это в «предпочтительном стиле».
  3. Новый код на уровне абстракции. Убедившись в том, что это действительно отдельный уровень кода, не должно возникнуть никаких затруднений в использовании предпочтительного стиля, даже если код много взаимодействует со старым стилем или стилями. Большая часть кода должна взаимодействовать с другими стилями, и я никогда не считал это проблемой.
  4. Очевидно, что сам API нуждается в наибольшей продуманности и отвечает требованиям максимального удобства использования.
  5. Любой пример или тестовый код должен также быть в состоянии быть написанным в предпочтительном стиле. В зависимости от полноты абстракции (то есть полностью ли скрывает нижние слои), это может быть легко или сложно. Конечно, обеспечение того, чтобы будущий клиентский код читался, будет одной из ваших основных задач.

Некоторые вещи, которые я нашел лично, это то, что с большой базой устаревшего кода:

  • Установка предпочтительного стиля и принудительное изменение кода не приводит к магическому переходу всего старого кода в новый стиль.

  • Большинству инженеров, как правило, нравится кодировать (более или менее) существующий стиль в данной библиотеке. Требование в противном случае приводит к значительному принуждению.

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

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

Кит
источник
0

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

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

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

+1 за метафайт.

theinsaneone
источник
Точно правильное решение ИМО. Я использую обертки для связывания кода, который другие люди пишут и для моих проектов. Определите интерфейс заранее, и затем, когда они реализуют его, вы можете обернуть его и проверить его в «черном ящике».
Кьевели
1
Почему это понижается? Я ясно думаю, что это лучшее решение :)
MetaFight
0

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

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

Густав Бертрам
источник