суббота, 10 октября 2015 г.

Делать быстро или качественно?

Постоянно возникают споры на эту тему как делать проект: качественно продумывая или быстро лишь бы работало?

Стартап.
Делаем быстро или качественно?
Конечно же быстро - ответят многие. Нам надо проверить гипотезу, а потом всё равно всё переделаем.

Сложившийся бизнес.
Делаем быстро или качественно?
Качественно и точка! У нас серьёзный бизнес!

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

В этой записи моё мнение.

качественно != медленно
быстро != просто

Это 2 главных тезиса.

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

Но обратное не верно. То что выглядит сложно не означает что оно решает сложную задачу реального мира. Самую простую задачу можно решить сложным путём чем создать видимость её сложности. Принцип KISS - против этого, а не против сложных систем вообще. Сложные системы сложны потому что решают сложную задачу реального мира, а не потому что junior начитался "Банды 4-х" и решил всё это применить в проекте.

Все техники "правильного кода" направлены на управление сложностью. Абстракция - наверное главный концепт в electrical engineering & computer science - ни что иное как хак, позволяющий сохранять сложность отдельных компонентов системы на уровне, посильном человеческому мозгу т.к. сложность всей системы в целом уже вышла за пределы его возможностей. Будь мы в 100 раз умнее, наверное, не нужно было бы разделать слой хранения данных и их представления - ведь это всё находилось бы под нашим контролем, и в очень маленьких проектах такой подход реально работает и оправдан. Но когда проект начинает расти нам становится всё сложнее понимать как он работает в целом и когда он уже не помещается у нас в мозгу - всё разваливается. Исправление багов становится единственным занятием, которые мы способны осилить и единственным чем мы занимаемся т.к. постоянно что-то ломается. Добавление новых функций влечёт за собой появление кучи новых багов в непредсказуемых местах.


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

Если проблема реального мира, которую ваш проект решает, проста настолько чтобы умещаться целиком в кэше мозга, то можно смело забить на все техники управления сложностью и делать "лишь бы работало". Этим вы, возможно, можете сэкономить 5-10-20% времени на реализацию, а сама она настолько проста, что можно просто взять переписать всё с нуля "по-нормальному" если это потребуется и это всё будет оправдано экономически.

Но если проблема реального мира сложнее чем вы можете уместить в голове? Тогда даже MVP её решения требует управления сложностью чтобы не заниматься бесконечным исправлением багов перед бета-релизом и успевать наращивать/менять функционал в процессе проверки гипотезы стартапа. Замахнувшись на сложную проблему реального мира вы обречены на необходимость управления сложностью в проекте. Иначе даже первые клиенты не смогут воспользоваться вашим проектом для решения этой проблемы из-за обилия ошибок и отсутствия необходимого функционала.

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

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

Делать качественно не значит делать сразу сложные фичи. Это значит делать важные фичи с минимально необходимой сложностью сохраняя возможность их изменения.
Делать "лишь бы работало" не значит делать важные фичи быстро с минимально необходимой сложностью. Это значит всего лишь делать "лишь бы работало".
Управление сложностью на ранних этапах проекта не означает его медленную реализацию. Противопоставление скорости качеству некорректно в отрыве от других факторов, таких как общая сложность решаемой проблемы реального мира.
Вася и Петя одновременно начали писать один и тот же продукт.
Вася был «ориентирован на результат» и начал сразу писать говнокод не продумав толком архитектуру.
А Петя месяц разрабатывал архитектуру, месяц делал удобный интуитивный интерфейс, которому позавидывал бы Джони Айв, потом месяц писал тесты, потом два месяца писал сам код и получил идеальное стабильное приложение.
Но Вася выпустил уже через месяц первую версию программы, пусть и не идеальную, пусть с багами, но рабочую, и начал её продавать. Ещё через месяц выпустил вторую версию исправляющие баги первой и добавляющие новые баги. Ещё через месяц на доходы от продаж нанял двух толковых программеров, которые за два месяца перелопатили весь код, согласно пожеланиям пользователей допилили интерфейс и выпустили третью версию программы.
Итого, через пять месяцев у Васи было два работника, куча клиентов и сносно работающее приложение отвечающее желаниям клиентов.
У Пети было вылизанное никому не известное приложение, минус на банковском счёте и ни одного клиента.
В завершение этого выдуманного примера можно сказать, что через полгода Вася купил все наработки Пети, Петю взял в штат тестировщиком, а сам по пьяни разбился на своём новеньком Туареге

Первоисточник установить не удалось.

Отсутствие измеримых метрик в разработке софта порождает массу мифов (https://leanpub.com/leprechauns). В анекдоте выше обострено противоречие - отличный приём чтобы лучше понять суть проблемы. Отождествление говнокода и высокой скорости разработки - один из мифов. Но что такое говнокод? Где научное сравнение скорости разработки с помощью "паттерна говнокод" и "паттерна идеальная архитектура" одинакового проекта двумя командами одинаковых специалистов в одинаковых условиях? Иными словами - научный эксперимент, в котором зафиксированы все факторы кроме независимой переменной и результат зависит только от её изменения и ничего больше. Один из таких экспериментов привёл, например, к появлению мифа о "10x engineer". Может быть говнокод - это код написанный без применения практик управления сложностью. Но тогда он действительно оправдан в простом проекте (который умещается в голове 1 человека) и не оправдан в сложном. Но как определить на старте проекта его сложность? Зная что нам свойственно считать любую задачу простой уловив лишь поверхностно основной принцип ("искусственный интеллект - фигня, есть rubygem с реализацией нейронной сети, чуток подкрутим и в продакшн").

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


Комментариев нет:

Отправить комментарий