О процессе разработки

  1. Код предназначен не только для его непосредственного выполнения, но он также является средством общения в команде и способом описать другим решение какой-либо проблемы. Написание читаемого кода — это фундаментальная часть данного процесса, а не просто “хороший тон”. Он включает в себя рефакторинг кода, выбор понятных имен переменных и добавление комментариев ко всему, что требует объяснений.
  2. Задумайтесь о том, что ваш pull request может сделать для пользователей и сообщества в целом, а не для вашего продвижения по карьерной лестнице. Избегайте “чрезмерного вклада” любой ценой. Не добавляйте функцию, если она не имеет никакого отношения к реальным целям вашего продукта.
  3. Наличие хорошего вкуса тоже относится к коду. Вкус — это процесс удовлетворения ограничений, регулируемый стремлением к простоте. Держите курс к простоте.
  4. Если кто-то просит вас добавить функцию —  это не означает, что вы обязательно должны ее добавить. Смело отвечайте “нет”. Каждая функция имеет стоимость, которая выходит за рамки первоначальной реализации: затраты на обслуживание, стоимость документации и ваши умственные затраты. Всегда спрашивайте: нам на самом деле необходимо это сделать? Зачастую, следует ответ: “Нет”.
  5. Помните, что на запрос пользователя о добавлении нового сценария использования не всегда стоит отвечать “да”, так как, зачастую, запрошенный сценарий не оптимален. Пользователи сосредоточены на своем конкретном сценарии использования, а вы должны быть сосредоточены на видении всего проекта в целом. Лучше займитесь улучшением существующих функций.
  6. Инвестируйте в непрерывную интеграцию и стремитесь к полному юнит-тестовому покрытию. Убедитесь, что вы находитесь в среде, где можете писать код четко и уверенно. Если это не так, начните с создания правильной инфраструктуры.
  7. Не переживайте, если не спланировали все заранее. Пробуйте все постепенно и смотрите, что из этого выходит. Если вас что-то не устраивает, как можно раньше откажитесь от этой идеи. Убедитесь, что вы создали среду, в которой это возможно сделать.
  8. Хорошее программное обеспечение упрощает процесс работы. Если задача выглядит сложной, это не означает, что ее решение тоже должно быть долгим и трудным. Слишком часто инженеры подбирают к непростым задачам такие же решения (Давайте использовать ML! Давайте создадим приложение! Давайте добавим блокчейн!) в ситуациях, когда доступна гораздо более простая, хотя и менее очевидная альтернатива. Прежде чем начать писать код, убедитесь, что решение вашей задачи упрощено до предела возможного. Исходите из своих “изначальных принципов”.
  9. Избегайте непонятных правил. Правила, которые вы разрабатываете, всегда должны быть ясными и доступными для других. Всякий раз, когда вы продумываете рабочий процесс (workflow), вы должны попытаться формализовать его в документированный процесс, чтобы другие участники команды смогли извлечь из него выгоду. Более того, вы должны стремиться автоматизировать ваши рабочие процессы с помощью ПО (например, проверку корректности).
  10. Ваш выбор должен влиять на весь процесс проектирования, а не только на доход и развитие. Какое влияние оказывает ваше программное обеспечение на пользователей и на мир? Есть ли нежелательные побочные эффекты, которые перевешивают пользу? Что вы можете сделать, чтобы решить их, сохранив при этом всю пользу программного обеспечения?

О проектировании API

  1. У вашего API есть пользователи, следовательно, у API есть пользовательский опыт (UX). При принятии какого бы то ни было решения — всегда помните о пользователях. Думайте о чувствах каждого пользователя, будь то новичок или опытный разработчик.
  2. Старайтесь свести к минимуму умственную нагрузку на пользователей, во время использования API. Автоматизируйте то, что можно автоматизировать, снизьте количество действий и выборов, необходимых от пользователя. Не добавляйте параметры, которые не имеют значения, разрабатывайте простые и последовательные процессы работы, которые отражают простые и последовательные ментальные модели.
  3. Простые вещи должны быть простыми, сложные вещи должны быть возможными для выполнения. Не увеличивайте, даже минимально, умственную нагрузку сценариев общего использования, ради нишевых сценариев использования.
  4. Если умственная нагрузка рабочего процесса достаточно низкая, у пользователя должна быть возможность делать все по памяти (не используя документацию или учебник) после того, как он сделал это один или два раза.
  5. Стремитесь к тому, чтобы ваш API соответствовал ментальным моделям экспертов доменов и практических специалистов. Если у кого-то есть опыт работы с доменами, но нет опыта работы с вашим API — у него должна быть возможность интуитивно понимать ваш API, используя минимальное количество документации, в основном, просто взглянув на несколько примеров кода, доступные объекты и их сигнатуры.
  6. Значение аргумента должно быть понятным без какого-либо контекста, относительно базовой реализации. Аргументы, которые указываются пользователями, должны относиться к ментальным моделям, которые пользователи относят к определенной проблеме, а не к деталям реализации в вашем коде. API — это всегда о проблемах, которые решает код, а не о том, как программное обеспечение работает на заднем плане.
  7. Наиболее мощные ментальные модели обладают модульностью и иерархичностью. Точно так же хороший API обладает модульностью и иерархичностью: простой в обращении, однако выразительный. Существует баланс между сложными сигнатурами на меньшем количестве объектов и наличием большего количества объектов с более простыми сигнатурами. Хороший API имеет разумное количество объектов с достаточно простыми сигнатурами.
  8. Ваш API неизбежно отражает ваши варианты реализации, в частности, ваш выбор структур данных. Чтобы получить интуитивно понятный API, вам необходимо выбрать структуры данных, которые, естественным образом, подходят для домена —  это соответствует ментальным моделям экспертов в области доменов.
  9. Умышленно проектируйте сквозные рабочие процессы, а не набор атомарных функций. Многие разработчики, проектируя API, задаются вопросом: “Какие возможности нам нужно добавить?”. Вместо этого лучше спросить: “Каков сценарий использования для этого инструмента?”. Какова оптимальная последовательность действий пользователя для каждого сценария использования? Какой самый простой API может поддерживать этот рабочий процесс? Атомарные функции в вашем API должны отвечать на явную потребность, возникающую в высокоуровневом рабочем процессе. Функции по типу “вдруг кому-то это может понадобиться” не следует добавлять. Они не нужны!
  10. Сообщения об ошибках, и, как правило, любая обратная связь, предоставляемая пользователю в процессе взаимодействия с вашим API —  это часть API. Интерактивность и обратная связь являются неотъемлемой частью пользовательского опыта. Нарочно создавайте сообщения об ошибках в API.
  11. Код — это средство общения, поэтому так важно присваивать имена, например, проекту или переменным. Имена отражают ваше отношение к проблеме. Избегайте распространенных названий (x, variable, parameter), избегайте ЧрезмерноДлинныхИСпецифичныхНазваний, избегайте терминов, которые могут создать ненужные разногласия (master, slave) и убедитесь, что вы последовательны в выборе имен. Последовательность в выборе имен означает как внутреннюю последовательность (не называйте “dim”, то что называется “axis” в других местах), так и последовательность с установленными соглашениями для проблемного домена. Прежде чем выбрать имя, обязательно проверьте существующие имена, используемые экспертами в области доменов (или другими API).
  12. Документация занимает центральное место в UX вашего API. Она не является дополнением к API, как многие ошибочно полагают. Инвестируйте в высококачественную документацию и вы получите более высокую прибыль, чем при инвестировании в другие функции.
  13. Показывайте, а не рассказывайте: ваша документация не должна говорить о том, как работает программное обеспечение, она должна показывать, как его использовать. Продемонстрируйте примеры кода для сквозных рабочих процессов; примеры кода для каждого распространенного сценария использования и ключевых функций вашего API.

О карьере в сфере программной инженерии

  1. Карьерный рост —  это не то, каким количеством людей вы управляете, а то какое влияние вы оказываете: разница между миром, в котором есть ваши плоды работы и миром, где их нет.
  2. Разработка программного обеспечения — это командная работа; речь идет как о взаимоотношениях, так и о технических навыках. Будьте хорошим товарищем. Когда вы целенаправленно идете к своей цели, не забывайте о других людях.
  3. Технологии никогда не бывают нейтральными. Если ваша работа оказывает какое-то влияние на мир, то это влияние имеет нравственный характер. Казалось бы, безобидный технический выбор, который мы делаем в программных продуктах, моделирует условия доступа к технологии; стимулы ее использования; кто выиграет, а кто пострадает от этого. Технический выбор — это также этический выбор. Поэтому всегда будьте целенаправленны и откровенны, относительно ценностей, которые вы хотите поддерживать и продвигать. Воплощайте свои ценности в своих творениях.
  4. Самоуправление — свобода воли в работе и складывающихся обстоятельствах — это ключ к удовлетворенности жизнью. Убедитесь, что вы предоставляете достаточно самостоятельности окружающим вас людям и убедитесь, что выбранная вами карьера приведет к большей свободе воли для вас.
  5. Создайте для мира то, что нужно ему, а не то, что хочется вам. Слишком часто инженеры живут в своем выдуманном мире, сосредоточившись на продуктах, удовлетворяющие их конкретные потребности. Ищите возможность расширить свой жизненный опыт, который позволит вам лучше понять, что нужно миру.
  6. Делая выбор с долгосрочными последствиями, ставьте свои ценности выше краткосрочных личных интересов, а также отбрасывайте ненужные эмоции, например, жадность или страх. Позвольте вашим ценностям, а не эмоциям вести вас.
  7. Когда вы вступаете в конфликт, сделайте паузу и напомните друг другу об общих ценностях и целях. Наверняка вы находитесь на одной стороне баррикад.
  8. Продуктивность сводится к высокой скорости принятия решений и склонности к действию. Это требует: a) хорошей интуиции, которая основывается на жизненном опыте, чтобы принимать правильные решения при минимуме информации; б) четкое понимание того, когда нужно действовать более осторожно и ждать дополнительной информации, поскольку цена неправильного решения будет выше, чем стоимость отсрочки. Оптимальный компромисс между скоростью и качеством принятия решений может сильно отличаться при различных условиях.
  9. Быстрое принятие решений увеличивает количество решений, которые вы совершаете в течение всей своей карьеры. В итоге это приводит к повышению уровня вашей интуиции при принятии решений. Опыт является ключом к высокой производительности, а высокая производительность дает вам больше опыта: весьма эффективный цикл.
  10. В ситуациях, когда вы осознаете, что интуиция не помогает, придерживайтесь абстрактных принципов. Создайте список проверенных принципов и пополняйте его на протяжении всей карьеры. Принципы — это официально оформленная интуиция, которая затрагивает более широкий круг ситуаций и требует от вас намного меньше опыта.

 

Перевод статьи François Chollet: Notes to Myself on Software Engineering

Предыдущая статьяЧто вы знаете о типах данных Java?
Следующая статьяПлюсы и минусы программирования на Java