В этой публикации я хотел бы представить дорогому читателю некоторые принципы, которыми я руководствуюсь при выполнении своих обязанностей как разработчика Python. С одной стороны, мне хотелось поделиться накопленным опытом, который может быть полезен начинающим разработчикам, а с другой – получить обратную связь от более опытных разработчиков, менеджеров и специалистов в смежных областях.
Принципы условно сгруппированы в три группы: принципы принятия решений; принципы, направленные на улучшение качества кода; принципы, направленные на улучшение производительности кода.
- Принимая решения
- Любое техническое решение должно быть обосновано.
- Ответственность за решение всегда лежит на лице или лицах, принявших решение.
- При принятии технических решений необходимо учитывать их влияние во времени и их соответствие потребностям бизнеса.
- Одним из основных критериев при принятии технических и других решений должна быть их наибольшая эффективность.
- Не стесняйтесь отклоняться от правил, методологий, шаблонов и других ограничений, если эффект от такого отклонения превышает возможные потери (Особые случаи не настолько особенные, чтобы нарушать правила, хотя практичность превосходит чистоту).
- При необходимости сразу создайте работающее, но, возможно, не самое лучшее решение, а затем улучшите его (лучше сейчас, чем никогда, хотя никогда часто лучше, чем *прямо* сейчас).
- Если сложно выбрать между двумя альтернативными техническими решениями, то нужно выбрать любое и двигаться дальше, при появлении дополнительной информации можно провести рефакторинг, если решение оказалось неоптимальным.
- Гибкость технических решений крайне желательна, но универсальность не требуется.
- Любое техническое решение должно быть обосновано.
- Качество исходного кода
- Качество кода должно быть оптимизировано на основе развитой системы критериев, сбалансированной по затратам в краткосрочной и долгосрочной перспективе.
- Сразу пишите оптимальный код, если это не увеличивает его сложность и время разработки (Лучше красивое, чем уродливое)
- Самодокументируемый код имеет приоритет над хорошо прокомментированным кодом (красивое лучше, чем уродливое).
- Напишите TODO и FIXME в коде.
- Дайте переменным, функциям, методам, классам и другим объектам исходного кода имена, которые точно отражают их назначение, несмотря на увеличение длины имен (явное лучше, чем неявное).
- Предпочтительно меньшее количество строк и меньший объем кода, при сохранении одинаковой читабельности кода (Простое лучше сложного)
- Используйте проверку кода как инструмент для обнаружения ошибок, согласования стиля разработки, знакомства с кодом других людей и обучения в команде.
- Повторно используйте свой и чужой код
- Используйте специализированные библиотеки для решения конкретных задач вместо разработки собственного аналогичного кода.
- Качество кода должно быть оптимизировано на основе развитой системы критериев, сбалансированной по затратам в краткосрочной и долгосрочной перспективе.
- Производительность
- Производительность разработки кода имеет приоритет над производительностью выполнения кода.
- Оптимизация производительности выполнения кода должна быть обоснована соответствующей необходимостью.
- Оптимизация производительности выполнения кода должна осуществляться путем устранения наиболее серьезных узких мест.
- Прежде всего, следует использовать наиболее эффективные методы оптимизации производительности выполнения кода.
- Производительность разработки кода имеет приоритет над производительностью выполнения кода.
Для некоторых принципов в скобках указаны постулаты Дзен Питона, которые, на мой взгляд, относятся к этим принципам или их частям.
Принимая решения
Любое техническое решение должно быть обосновано.
Любое техническое решение должно быть обосновано: от синтаксических конструкций, используемых в коде, до архитектурных решений самого высокого уровня.
Для меня обоснованность технического решения означает наличие аргументов, подтверждающих его преимущества, неизбежность такого решения или иную осуществимость этого решения.
Обоснование должно сопровождаться знанием о недостатках этого решения и планом их преодоления или обоснованием их незначительности.
Кроме того, следует рассматривать альтернативные решения, обосновывая их меньшую привлекательность по сравнению с выбранным решением.
В обосновании необходимо учитывать как технические, так и организационные аспекты, связанные с конкретным техническим решением.
Если различные аргументы противоречат друг другу, то следует руководствоваться экономическим эффектом того или иного решения для бизнеса с учетом краткосрочной и долгосрочной перспективы.
Аналогично следует применять этот принцип и в вопросах нетехнического, в том числе организационного характера.
Этот принцип противостоит шаблонному принятию решений, а также необдуманному принятию первого попавшегося решения без должного анализа альтернатив.
Ответственность за решение всегда лежит на лице или лицах, принявших это решение.
Этот принцип направлен на повышение качества принимаемых решений и противостоит бессистемному принятию решений.
При принятии технических решений необходимо учитывать их влияние во времени и их соответствие потребностям бизнеса.
Необходимо учитывать, какое влияние окажет то или иное решение как в краткосрочной, так и в долгосрочной перспективе, а также будет ли это техническое решение полезно для бизнеса в эти периоды.
Данному принципу противостоит одностороннее принятие решений с концентрацией результатов только в краткосрочной перспективе или только в долгосрочной перспективе, а также без учета потребностей бизнеса и учета влияния на бизнес.
этих решений, концентрируясь исключительно на технических преимуществах решения.
Одним из основных критериев при принятии технических и других решений должна быть их наибольшая эффективность.
Под эффективностью в этом деле я понимаю соотношение ценности полученного для бизнеса результата к сумме необходимых для этого затрат.
Этот принцип противоположен подходу, учитывающему только ценность полученного результата, независимо от необходимых затрат.
Не стесняйтесь отклоняться от правил, методологий, шаблонов и других ограничений, если эффект от такого отклонения превышает возможные потери (Особые случаи не настолько особенные, чтобы нарушать правила, хотя практичность превосходит чистоту).
Правила, методики, шаблоны и другие ограничения представляют собой обобщение предыдущего опыта с целью получения стабильного результата деятельности при определенных условиях.
Однако в конкретных случаях условия могут отличаться, поэтому необходимо осознанно подходить к использованию накопленного опыта и при необходимости вносить коррективы.
Этот принцип противостоит догматическому следованию правилам, методологиям, шаблонам и другим принятым ограничениям без учета окружающей действительности.
При необходимости вам следует сразу найти решение, которое работает, но может быть не лучшим, и улучшить его позже (лучше сейчас, чем никогда, хотя никогда часто лучше, чем *прямо* сейчас)
Бывают ситуации, когда необходимо реализовать определенный функционал или исправить дефект в сжатые сроки, а есть альтернативные решения: быстрые и хорошие.Быстрый способ может дать немедленные результаты, но в долгосрочной перспективе может создать осложнения и привести к дополнительным затратам.
И принятие хорошего решения – это долго и затратно в краткосрочной перспективе, но в долгосрочной перспективе оно окупится и принесет значительно больше пользы, чем требовалось.
В этом случае эффективным будет сочетание обоих решений, а именно: мы принимаем быстрое решение сейчас и принимаем хорошее решение, как планировалось.
В сумме это получится немного дороже, чем реализация только одного из решений, но эффект от их сочетания окупит затраты.
Этот принцип противоречит попыткам сделать все идеально сразу.
Если сложно выбрать между двумя альтернативными техническими решениями, то нужно выбрать любое и двигаться дальше, при появлении дополнительной информации можно провести рефакторинг, если решение оказалось неоптимальным.
Без комментариев
Гибкость технических решений крайне желательна, но универсальность не требуется.
Гибкость – это способность адаптировать техническое решение к новым условиям, которые могут появиться в будущем.
Универсальность – это фактическая адаптация технического решения к возможности использования для набора условий.
Зачастую обеспечение универсальности требует большего труда, чем обеспечение гибкости, поскольку учитывает большее количество условий, с которыми должно быть совместимо техническое решение.
Кроме того, обеспечение универсальности может быть неэффективным, поскольку требует адаптации к условиям, которые еще не возникли и могут никогда не возникнуть.
Кроме того, иногда унификация требует обобщений, которые трудно реализовать.
Поэтому гибкость технических решений весьма желательна, но универсальность не требуется.
Этот принцип противопоставляется попытке сразу принять универсальные решения, которые впоследствии оказываются невостребованными из-за изменения внешних условий.
Качество исходного кода
Качество кода должно быть оптимизировано на основе развитой системы критериев, сбалансированной по затратам в краткосрочной и долгосрочной перспективе.
Мой основной приоритетный состав критериев оптимизации следующий (при необходимости его следует корректировать под конкретные условия):
- Высокая читаемость кода — чем легче понять код, тем лучше (читаемость имеет значение)
- Низкая цикломатическая сложность кода — чем меньше ветвей, циклов, условных операций, вызовов функций и методов, тем лучше (Простой лучше сложного.
Плоский лучше вложенного)
- Высокая гибкость кода — чем проще вносить изменения в код, тем лучше (данный критерий оптимизации увеличивает затраты на разработку в краткосрочной перспективе, но снижает их в долгосрочной перспективе)
- Небольшой объем кода — чем меньше кода, тем лучше (простое лучше сложного)
- Производительность выполнения кода — чем быстрее выполняется код, тем лучше
Этот принцип противостоит хаотичной оптимизации качества кода, а также использованию несогласованных между членами команды разработчиков критериев оптимизации и их приоритетов.
Сразу пишите оптимальный код, если это не увеличивает его сложность и время разработки (Лучше красивое, чем уродливое)
Иногда существует несколько конструкций кода, которые функционально эквивалентны, но имеют разную производительность.Как правило, достаточно один раз выяснить, какая конструкция имеет большие требования к производительности или памяти и использовать ее во всех подобных случаях.
Однако следует учитывать, что некоторые подобные конструкции могут ухудшить читаемость кода и увеличить время разработки как на момент написания кода, так и при его сопровождении и изменении в будущем.
Это следует учитывать, чтобы избежать недостатков преждевременной оптимизации.
Самодокументируемый код имеет приоритет над хорошо прокомментированным кодом (красивое лучше, чем уродливое).
Иногда комментарии помогают разобраться в сложном коде, но в то же время являются показателем низкой читабельности кода.
Поэтому в случаях, когда возникает необходимость написать комментарий, следует подумать, какие изменения можно внести в код, чтобы необходимость в комментарии отпала.
Вот типичные, на мой взгляд, случаи, когда можно обойтись без комментариев:
- Комментарий содержит уточнение смысла данных, содержащихся в переменных - исправляется переименованием переменной (аналогично применимо к именам классов, методов, функций, констант и т.д.)
- Изолирование блока кода с помощью комментария — это можно исправить, вынеся блок кода в отдельную функцию или метод.
- Объявление действия, которое необходимо выполнить на уровне семантики языка - исправлено удалением комментария (пример комментария, который необходимо удалить: a = 10 # присвоить 10 a)
- Документирование общедоступного API
- Объяснение неочевидных причин, выбор альтернативного технического решения.
- Пояснение оптимизированного и, как следствие, сложного для понимания участка кода
- TODO и FIXME — микропланирование в контексте исходного кода
.
Поэтому комментарии должны быть разумными.
Этот принцип противоречит чрезмерному использованию комментариев.
Напишите TODO и FIXME в коде.
Не всегда имеет смысл делать все в момент написания конкретного фрагмента кода, особенно если речь идет о рефакторинге и внесении изменений, актуальность которых под вопросом.
В таких случаях разумно написать в коде комментарий TODO или FIXME, над которым вы сможете поработать в более подходящий момент. Целесообразно сразу присвоить этому замечанию примерный приоритет, чтобы упростить дальнейшее планирование.
Этот принцип противоречит написанию идеального кода без учета реальной необходимости и стоимости такого кода в конкретный момент времени.
Дайте переменным, функциям, методам, классам и другим объектам исходного кода имена, которые точно отражают их назначение, несмотря на увеличение длины имен (явное лучше, чем неявное).
«Экономия на длине имен не может быть достигнута за счет понятности кода.
Предпочтительно меньшее количество строк и меньший объем кода, при сохранении одинаковой читабельности кода (Простое лучше сложного)
Есть исследования, из которых следует, что количество ошибок, допущенных в коде, в среднем прямо пропорционально длине кода и количеству строк кода в частности.Объясняется это следующим образом: во-первых, чем меньшая часть кода умещается на экране одновременно, тем больше усилий требуется для запоминания невидимых в данный момент участков кода при разработке, а во-вторых, чем длиннее код, тем больше опечаток может быть.
в нем могут быть допущены и другие ошибки, связанные с человеческим фактором.
Используйте проверку кода как инструмент для обнаружения ошибок, согласования стиля разработки, знакомства с кодом других людей и обучения в команде.
Помимо своей непосредственной цели, проверка кода отлично подходит для согласования стиля разработки, знакомства с кодом других людей и обучения в команде.
В идеале в общую ветку следует включать только код, прошедший проверку кода.
Повторно используйте свой и чужой код
Этот принцип следует из принципа DRY. Чтобы успешно применить этот принцип, необходимо хорошо владеть кодовой базой, и в этом помогает использование проверки кода всеми членами команды разработчиков.
Используйте специализированные библиотеки для решения конкретных задач вместо разработки собственного аналогичного кода.
Если вам необходимо решить какую-то задачу (например, отправить письмо по smtp), вам следует ознакомиться с наличием готовых библиотек для этой задачи и изучить возможности их использования.
Отказ от использования специализированных решений должен быть обоснован, поскольку специализированные решения имеют ряд преимуществ перед новыми разработками.
Специализированные решения уже разработаны и протестированы.
Это означает экономию времени на разработку, тестирование и исправление дефектов.
Иногда кажется, что проще разработать собственный код для выполнения необходимой функции, поскольку использование готового решения требует затрат времени на обучение и есть риск, что оно будет потрачено впустую, поскольку окажется, что решение не подходит. Однако это впечатление часто оказывается обманчивым, во-первых, из-за недооценки сложности задачи, во-вторых, из-за наличия других преимуществ.
Особенность специализированных решений в том, что они созданы специально для решения конкретной задачи.
Это означает, что они учитывают особенности, которые сложно учесть при решении конкретной задачи наряду с основной.
Следует понимать, что помимо функциональности решение должно удовлетворять и нефункциональным требованиям, таким как требования к производительности, безопасности, простоте обслуживания, совместимости и другие.
Все эти возможности требуют глубокого погружения в задачу и в случае их разработки могут быть упущены из виду из-за ограниченности времени.
Часто специализированные решения являются общедоступными и поэтому используются многими разработчиками.
Это означает, что недостатки, с которыми они столкнулись при практическом использовании, уже выявлены и устранены.
Таким образом, специализированные решения позволяют использовать чужой опыт без дополнительных трудозатрат. Публичные специализированные решения часто имеют открытый исходный код. Фактически, большинство библиотек Python именно такие.
Подобные решения постоянно разрабатываются сообществом разработчиков, поэтому появляется возможность без дополнительных трудозатрат повысить качество вашего ПО за счет обновления используемых версий.
Зачастую разные публичные решения легко интегрируются друг с другом (например, Spyne и SQLAlchemy), что позволяет существенно снизить затраты на разработку.
Существует ряд обоснованных причин не использовать специализированное решение.
Примеры таких причин:
- Специализированное решение лишено необходимого функционала
- Пользовательское решение плохо документировано, а доступ к исходному коду невозможен или ограничен, либо исходный код слишком сложен для использования вместо документации.
- Кастомное решение содержит серьезные ошибки и плохо поддерживается, либо нет доступа к исходному коду или возможности самостоятельно исправить ошибки.
- Поддержка кастомного решения официально прекращена.
- Текущие потребности в функционале специализированного решения составляют крайне малую долю от общего функционала, заложенного в специализированное решение.
Производительность
Производительность разработки кода имеет приоритет над производительностью выполнения кода.
В современных условиях стоимость человеческих ресурсов обычно выше стоимости оборудования, поэтому для меня производительность разработки кода (выраженная в количестве разрабатываемого функционала в единицу времени) имеет приоритет над производительностью исполнения кода.
Этот принцип противостоит преждевременной оптимизации производительности выполнения кода.
Оптимизация производительности выполнения кода должна быть обоснована соответствующей необходимостью.
Обоснование состоит в том, чтобы сформулировать требования к производительности, основанные на практическом или запланированном масштабе использования информационной системы, а затем выявить несоответствие информационной системы этим требованиям.
Этот принцип противостоит преждевременной оптимизации производительности выполнения кода.
Оптимизация производительности выполнения кода должна осуществляться путем устранения наиболее серьезных узких мест.
Для этого необходимо выявить узкие места, оценить вклад каждого узкого места в снижение производительности и в первую очередь оптимизировать самое большое узкое место.Этот принцип противостоит хаотичной оптимизации производительности выполнения кода.
Прежде всего, следует использовать наиболее эффективные методы оптимизации производительности выполнения кода.
Эффективность методов оптимизации – это отношение доли прироста производительности к общим затратам на выполнение оптимизационных работ. Для меня основным является следующий приоритетный список методов оптимизации:
- Изменение алгоритма обработки данных (может повысить производительность до нескольких порядков при относительно небольших затратах на разработку)
- Увеличение мощности оборудования (может обеспечить рост производительности от десятков процентов до нескольких десятков раз, в зависимости от характера ухудшения производительности; данный метод может потребовать внесения изменений в архитектуру информационной системы для обеспечения возможностей масштабирования)
- Обновление готового прикладного и системного ПО, используемого в информационной системе (предполагает небольшие затраты, за исключением платного ПО, но это редко дает существенный прирост производительности, поскольку прикладное и системное ПО обычно изначально оптимизируются)
- Изменение языка разработки в условиях узких мест, либо полный переход на более производительный язык программирования (высокие затраты на разработку с увеличением производительности от десятков процентов до нескольких десятков раз, в зависимости от характера функциональности информационной системы и используемые языки программирования)
-приоритетный метод оказывается выше.
Этот принцип противостоит хаотичной оптимизации производительности выполнения кода.
Заключение
Я сознательно исключил из публикации некоторые принципы, поскольку они больше касаются управления людьми, общения между людьми и построения процессов разработки, чем непосредственно написания исходного кода.Я просто не смог хорошо определить или сформулировать некоторые принципы, поскольку перевод бессознательных знаний в осознанные – это достаточно сложный процесс.
Поэтому я очень надеюсь, что комментарии к статье будут не менее интересны, чем сама статья, и позволят мне написать продолжение, включив недостающую информацию.
Теги: #разработка #принципы #python #разработка сайтов
-
Самые Востребованные Картриджи Kodak
19 Oct, 24 -
«Консольные Войны»: Sega Против Nintendo
19 Oct, 24 -
Весь Мир Против Коронавируса. Истории Intel
19 Oct, 24 -
Обновление Политики Паролей Ripe Ncc
19 Oct, 24 -
Ноутбук С Двумя Дисплеями
19 Oct, 24