среда, 14 марта 2012 г.

О «достаточно хорошем» ПО

Сегодня на ежедневном Stand-up'е я произнёс перед командой очень проникновенную речь о том, что мы пишем софт для людей и никого не интересует, насколько красиво код будет выглядеть изнутри, если пользователю будет неудобно с ним работать.

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

И, конечно же, я сразу же вспомнил концепцию о достаточно хорошем (good enough) ПО. Итак, вот её основной постулат: мы не стремимся сделать идеально, мы не пишем как попало, мы делаем достаточно хороший продукт.

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

Качество

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

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

В среднестатистическом же бизнес-приложении количество ошибок и недочётов может быть достаточно большим. Иногда, ужасающе большим. И, тем не менее, система будет вполне успешна, если, конечно, не будет отказов в большинстве стандартных вариантов использования. Мы не будем считать такое ПО идеальным, но будем считать его достаточно хорошим.

Архитектура и код

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

Мы теряем день за днём, оттачивая своё лётное мастерство, но лететь никуда так и не собираемся. Мы не можем остановиться и сказать: «Всё! Теперь — можно лететь», потому что всегда находится ещё пара-тройка не до конца освоенных лётных приёмов: бочка, петля Нестерова и другие (столь же не нужные в гражданской авиации) трюки.

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

Функциональность

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

Тут я, конечно же, не говорю о продуктах, основной изюм которых – позволить пользователю «сделать всё». Такие тоже бывают. Например, один наших продуктов (не буду конкретизировать, чтобы меня не объявили в рекламе ;) основан именно на этом преимуществе.

Посмотрите на Twitter. Его функциональность минимальна. Она достаточна для того, чтобы пользователи могли отправлять свои сообщения и читать чужие. Ни возможности добавлять в сообщения картинки («а как вообще можно без них», подумают многие), ни полноценной социальности (только Follow и reply), ничего лишнего 
Позднее вставка картинок всё-таки появилась, но сильно после того, как Twitter обрёл свою популярность.
Посмотрите на Google. Он так и не сделал категории, которые в то время были у всех поисковиков и сложно было представить, как вообще «можно без них».
Говорят, что они всё-таки есть, и до них можно добраться, но 90% пользователей их в глаза не видела.
Чем больше фич вы пытаетесь добавить в продукт, тем больше размываются его основные достоинства. Поэтому, функциональность должна быть достаточной, чтобы выполнять ту основную задачу, ради которой вы его создали.

Несколько строк в завершение

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

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

6 комментариев:

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

    ОтветитьУдалить
    Ответы
    1. Я бы сказал, что маркетинг даёт всё. Но в широком понимании. Всегда необходимо учитывать несколько стандартных факторов:
      1. Для кого продукт пишется
      2. Чего они хотят (т.е. бизнес-задача)

      Можно ещё учитывать, к чему они привыкли, но этот пункт весьма спорный. Иногда юзера стоит ломать. Но только, если вы уверены в своей гениальности, как Джобс, например

      Удалить
  2. В моем понимании есть конкретный принцип, который обеспечивает "достаточно хорошее" ПО - это high cohesion and low coupling. Принцип универсальный и применим не только к ПО. :)

    ОтветитьУдалить
    Ответы
    1. Отличный принцип, кстати. Но его очень по-разному понимать можно. Например, Как тебе high cohesive класс, который выполняет "маленькую и конкретную задачку" отображения пользовательского интерфейса? :)

      Удалить
    2. Из самой формулировки "отображение пользовательского интерфейса" следует, что эта задача неконкретная и немаленькая. :) Конкретная задача - это реализовать элемент пользовательского интерфейса, который выглядит так-то и выполняет такие-то функции.

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

      Удалить