SOLID’ный тимлид, или основы менеджмента для технарей

Часто получается так, что тимлидом в команде становится самый прокачанный разработчик, который хорош в hard skill’ах, но менеджментом до этого не занимался. Пару лет назад у меня появилась мысль сделать доклад про основы менеджмента для технарей. И вот спустя 2 года я выступил на Teamlead Conf 2021 с темой, вынесенной в заголовок статьи. Запись выступления доступна ниже, ну а дальше пойдет текстовое содержание доклада.

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

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

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

И это задача тимлида — сделать ее идеальной. А теперь давайте подумаем как ее решать, но не будем забывать, что мы — технари:)

Принципы ООП

Для этого вспомним принципы объектно ориентированного программирования, которые знает почти любой джун, а именно

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

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

Следующий принцип — это инкапсуляция. В этом принципе есть дуальность — публичная и скрытая часть. Интерфейсом команды для заказчика является тимлид, который выступает как входная точка для “хотелок” и вопросов заказчика. Скрытой частью является устройство команды.

Интересно, что реализация скрытия может быть разной, например

  • как black box — команда на стороне подрядчика, которая работает по fix price
  • как gray box — команда на стороне подрядчика, которая работает по time & materials
  • как white box — inhouse команда

Следующие принципы рассмотрим совместно, а именно наследование и полиморфизм. Если посмотреть на нашего бизнес-заказчика, то для реализации потока его блестящих идей ему требуется участие целого ряда отдельных команд. Если бизнес средний и тем более крупный, то это взаимодействие может быстро стать нетривиальным, если команды не обладают общим интерфейсом:) В итоге, часто есть стандартный формат взаимодействия, который можно рассматривать как абстрактный класс Team. Конкретные команды наследуются от этого абстрактного класса и заказчики могут полиморфно ставить свои задачи не важно это команда разработки api, веба или мобильного приложения. Конечно в реальной жизни все чуть сложнее, но целевая схема такая.

Выше мы поговорили про то, как команда выглядит снаружи, но для тимлида важно и внутреннее устройство, т.к. он как Харон стоит на границе и выступает в качестве интерфейса взаимодействия двух миров. Давайте заглянем внутрь команды и поговорим про роли, к которым тоже отлично применяются принципы ООП. И рассмотрим мы на примере роли Developer.

Если вы хоть раз писали описание вакансии для нового разработчика в вашу команду, то вы знакомы с абстракцией Developer, которой являются требования к позиции и обязанности, которые он будет исполнять в вашей компании. Конечно эта абстракция достаточна только в контексте найма и требует расширения в других bounded contexts. Подробнее про ограниченные контексты можете почитать в книгах про Domain Driven Design.

После выхода на работу разработчика инкапсуляция позволяет вам не париться о том, как он пишет код: под музыку или в тишине, копируя код со Stack Overflow или набивая его в VS Code с нуля и т.д. Главное, чтобы он выполнял свои обязанности и артефакты его работы были достаточного качества. Кстати, в рамках последнего года удаленной работы все привыкли к тому, что сокрытие информации — это норма. Кто из вас не обедал во время общих онлайн встреч просто отключив камеру в Zoom?:)

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

Принципы SOLID

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

Single Responsibility Principle

Техническое определение звучит так

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

Для команды это можно переформулировать так

Команда должна иметь определенную цель и все ресурсы для ее достижения должны быть инкапсулированы в нее

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

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

Open/Closed Principle

Техническое определение звучит так

программные сущности … должны быть открыты для расширения, но закрыты для модификации

Для ролей внутри команды это можно переформулировать так

Этот принцип применим к ролям в командах. А конкретно к построению матриц компетенций для разных уровней специалистов.

Тема матриц компетенций очень обширна, но если кратко, то нам надо построить таблицу, где в колонках расставлены специалисты, а в строках критерии

Например, такие

  • Execution — Какие задачи решает и что делает. За что отвечает в рамках создания наших продуктов
  • Technical Complexity — Насколько сложные технические задачи решает и каков у них уровень неопределенности
  • Ambiguity — Степень определенности, с которой работает
  • и т.д.

Liskov Substitution Principle

Техническое определение звучит так

Производный класс должен быть взаимозаменяем с родительским классом

Для команды это можно переформулировать так

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

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

  • junior developer
  • middle developer
  • senior developer
  • architect

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

  • junior analyst
  • middle analyst
  • senior analyst
  • architect

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

Эту проблему можно решить достаточно просто, если устранить неоднозначность термина “архитектор”. Разработчики обычно вырастают не просто в абстрактных архитекторов, а в software архитекторов, которые умеют проектировать системы и отлично писать код. А вот аналитики обычно дорастают до solution архитекторов, которые отлично умеют собирать требования и проектировать системы, которые удовлетворяют этим требованиям.

Если вам интересна эта тема, то подробнее про подходы к архитектурным решениям и виды архитекторов вы можете посмотреть в моем докладе на ArchDays 2020.

Interface Segregation Principle

Техническое определение звучит так

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

Мы уже говорили, что команда инкапсулирует внутри сложность и предоставляет наружу основной интерфейс в виде тимлида, но важно не завязывать все активности на тимлида, а активно распределять коммуникации и работу по людям, исполняющим разные роли внутри команды. Например, не по всем вопросам заказчик должен идти в тимлида — он может спокойно уточнить требования напрямую с аналитиком. Также разработчики из разных команд могут обсудить общие вопросы напрямую, а не через своих тимлидов и т.д. Если же все коммуникации проводить через тимлида, то он станет человеком-звездой и в определенные момент порвется:) Но важно, чтобы в процессах взаимодействия не просыпались общие договоренности — поэтому важно создавать артефакты по результатам работы, например, создавать отчеты по встречам, а точнее Meeting Notes.

Dependency Inversion Principle

Техническое определение звучит так

Зависимость на Абстракциях. Нет зависимости на что-то конкретное

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

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

В данной схеме есть несколько проблем:

  • с точки зрения тимлида — повышенные требования к тимлиду, т.к. он должен не просто сказать что надо сделать, но и объяснить как
  • с точки зрения разработчика — отсутствие возможности роста, решая задачи самостоятельно + скука, а дальше потенциальное увольнение
  • с точки зрения эффективности системы — 1) эффективность системы ограничена бутылочным горлышком в виде тимлида; 2) система не улучшается, т.к. все точки роста внутри команды закрыты тимлидом; 3) сложность системы ограничена размером головы тимлида:)

Как с этим всем нам поможет IoC? Легко. Тимлид должен транслировать не инструкции к задачам, а некоторые руководящие принципы, я назову их архитектурными. Эти принципы и подходы должны быть согласованы с командой. В итоге, когда тимлид будет ставить задачи, то его подчиненные будут их выполнять с учетом принципов, о которых они договорились заранее. Итоговая диаграмма выглядит следующим образом.

Здесь:

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

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

Подробнее про тему менеджмента здорового человека я рассказывал в статье “Подходы оркестровки и хореографии в мире менеджмента разработки ПО

Итоги

Есть очень известная цитата

В сущности, все модели неправильны, но некоторые полезны
Бокс, Джордж

Мы вместе вспомнили базовые принципы ООП и принципы SOLID для проектирования систем, а потом применили их к вопросам менеджмента. Надеюсь, что вам понравилось и вы найдете эти подходы полезными в своей работе:)

Источники

  1. Слайды этого доклада
  2. Статья по этому докладу «SOLID’ный тимлид, или основы менеджмента для технарей»
  3. Доклад «Современные подходы к разработке софта: с примерами из жизни Tinkoff» на Devfest 2020
  4. Доклад «A Как мы в Tinkoff принимаем архитектурные решения»
    на ArchDays 2020
  5. Статья «Принципы SRP и IoC в мире менеджмента разработки ПО»
  6. Статья «Подходы оркестровки и хореографии в мире менеджмента разработки ПО»
  7. Статья с обзором книги «What Is Domain-Driven Design?»

Director of digital ecosystem development department at Tinkoff. Bachelor at applied math, Master at system analysis, Postgraduate studies at economics.