КПД программиста

Почему один программист быстро решает задачи (то, что нужно пользователю), другой делает «отрицательную» работу — создает сложности и проблемы, которые другие должны преодолевать и исправлять?
Могут ли девять программистов за месяц сделать («родить») систему? Что такое дисциплина мышления и эффективные (точные и минимальные) коммуникации?

 

В работе…

1. Простота системы

Аксиома. Идеальная системы — меньше элементов, больше функций.

Очевидно, что простая система более эффективная и экономичная. Но, оказывается, что сделать систему простой и функциональной труднее, чем сделать ее запутанной и непонятной. Почему?

Давайте вначале обсудим, что такое программирование? Очевидный ответ — «создание программного кода» принципиально ошибочен, поскольку именно такой подход приводит к имитации программирования и бесконечной работе.

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

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

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

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

1.1 Процесс

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

К сожалению, качество требований и архитектуры не является очевидным количественным показателем, и не зависит от объема документов, используемых инструментов и нотаций, количества и статуса участников. Предлагаю пока ее оценивать субъективно: если программист по постановке задачи разработал простое и функциональное решение. Основным рабочим подходом является формализация требований.

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

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

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

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

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

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

1.1.1. Психология программиста

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

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

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

Рассмотрим два важных психологических аспекта в работе программиста: дисциплина мышления и мотивация.

tasks-to-work

Продуктивный и непродуктивный ритм

productive-work

unproductive-work

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

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

1.2. Опыт

1.2.1. Логика

Программист пишет сложный код из-за поверхностного понимания задачи (не произошла логическая свертка на основе полноты) или недостаточного уровня техники программирования.

1.2.2. Сотрудничество

2. Проект

3. Антипаттерны

Антипаттерны программиста

Кому много дадено, с того много спросится

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

  1. Применять все известные практики и паттерны анализа и проектирования, не задумываясь об их необходимости и согласованности.
  2. Чрезмерная зависимость и несогласованность работы программистов, приводящая к тому, что они друг другу мешают, и быстрее все сделать одному.
  3. Увлекаться техникой программирования и в ущерб пониманию требований и предметной области, проектированию и сотрудничеству в команде.
  4. Пассивное выполнение задачи — «делать как написано»: не задавать вопросы аналитику и коллегам если есть очевидные логические проблемы в постановке задачи или архитектуре решения.

Антипаттерны руководителя

На передней линии фронта в полный рост

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

  1. Планировать задачи и контролировать сроки, но не обеспечить четкую постановку задач и эффективное взаимодействие в команде и с заказчиком.
  2. Давать программисту задачи фрагментами и без предметной логики, не позволяя ему глубоко понять суть решения, обобщать задачи и разработать инфраструктуру для упрощения кода.
  3. Распределять задачи между программистами произвольным образом, чтобы нельзя было сделать правильную архитектуру, возникало масса вопросов и проблем с интеграцией кода.
  4. Ставить задачи в неправильном порядке, нарушая логику и нормальный процесс разработки, чтобы приходилось на каждом этапе переделывать ранее сделанную работу.
  5. Постоянно переключать программиста между задачами (не давая их закончить) и проектами, чтобы программист начал «просто писать код».
  6. Навязывать внешние регламенты и стандарты, отвлекающие программиста от реальных задач и мешающие ему работать.
  7. Игнорировать сообщения участников команды о проблемах проекта и предложения по их решения (или имитировать их принятие без реальных решений).

Антипаттерны аналитика

Свой среди чужих, чужой среди своих

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

  1. Писать много ненужной и непонятной документации и создавать много бессмысленных диаграм вместо общения с программистами и пользователями.
  2. Игнорирование опыта разработчиков в предметной области и их предложений по лучшей реализации.
  3. Выполнять чужую работу (технического писателя, тестировщика и пр.) вместо своей собственной работы: сбор и анализ требований, системный анализ, формализация, общение с разработчиками и заказчиком.