Именно так выглядят часы, дизайн которых придумал программист |
Не могу не поделиться замечательным случаем, который произошёл у нас в команде несколько дней назад.
В рамках нашего нового продукта ребята разрабатывали интерактивные виджеты для HTML5. И, в какой-то момент, дело дошло до анимации. Естественно, анимация представляла собой красивый и плавный переход между состояниями. Действительно, программисты довольно быстро и аккуратно всё реализовали, и я, вспомнив вебдевную молодость, выпросил недоделанный компонент "поиграться".
В качестве одного из "подопытных" компонентов я выбрал симпатичные аналоговые часики со стрелками. Конечно же, в тестовой версии, которую отдали мне программисты, положение всех трёх стрелок случайным образом изменялось раз в секунду, отлично иллюстрируя мировой хронометрический коллапс с идеальной, впрочем, анимацией.
Естественно, первым делом я попытался заставить их показывать правильное время. Поскольку программисты у нас хорошие, общая установка команды "делаем, чтобы было легко пользоваться", была выполнена, и часики начали показывать текущее время довольно быстро.
А может быть - вот так |
Но тут возникла непредвиденная заминка. Часы отлично шли до тех пор, пока секундная стрелка не доходила до отметки 59. А потом... Да, вы правы. Она красиво и плавно обращалась вспять и, пройдя весь циферблат в обратном порядке, возвращалась к отметке 0.
И ведь с точки зрения программистов всё выглядело логично! Действительно, чтобы анимировать переход от значения 59 к значению 0, надо, чтобы стрелка прошла в обратном порядке все числа от 59 до 0. Вот только в реальности никто никогда не видел часы, в которых стрелка возвращалась бы назад...
Итак, что же полезного мы можем вынести из этой ситуации?
- Во-первых: чтобы описать любой объект или явление, программистам приходится строить модель. По определению модели, часть факторов из реальной жизни остаётся "за бортом". И в этот момент особенно важно следить, чтобы модель, которую построили программисты, соответствовала модели, которую строит для себя пользователь. Действительно, когда я отключил анимацию, часы стали вести себя вполне ожидаемо (хотя и не так красиво).
- Во-вторых: тестирование должно обязательно проводиться на реальных данных в условиях, максимально приближенных к тем, который возникают у пользователя. Сейчас это кажется очевидным. Однако иногда, желая досконально протестировать работу продукта в граничных случаях и под нагрузкой, мы можем упустить проверку самых очевидных кейсов, которые, в силу их тривиальности, все просто игнорируют (и забывают).
- В-третьих: обычно программисты пишут программы, а не продукты. Они увлекаются описанием объектной модели, построением архитектуры и алгоритмов, забывая о том, что продукт должен собой представлять в реальности. То есть надо возвращать их с неба на землю. Здесь сильно помогает итеративный подход и частая демонстрация промежуточных результатов владельцу продукта (честно говоря, затрудняюсь более точно перевести скрамовское сочетание product owner).
- В-четвёртых: если вы пишите ТЗ на разработку внешней команде, по возможности описывайте исходный объект или процесс из реальной жизни, который лежит в основе создаваемого ПО. Это не только позволит программистам увидеть задачу шире, чем программный код, но и вы сможете более чётко сформулировать ключевые требования.С другой стороны я с огромным трудом представляю себе ТЗ, которое содержит фрагмент типа "при переходе от 59 к 0 стрелки должны двигаться по часовой стрелке". Такая детализация возможна разве что в системе жизнеобеспечения космического корабля, но мне такие задания, к сожалению, пока читать не доводилось. Поэтому описание реального объекта поможет команде более точно понять задачу.
- В-пятых: идеальный программист всегда немного аналитик. Он мыслит не только интерфейсами, классами и методами, но и объектами предметной области, понимает не только алгоритмы, но и бизнес-логику системы. И это одна из основных черт, которая отличает опытного разработчика от начинающего кодера (каким бы классным он ни был).
В заключение хочу сказать, что никоим образом не пытаюсь посмеяться над "глупыми программистами" или как-то ещё задеть их в профессиональном плане. У меня отличные ребята и классная команда. Просто есть вещи, которые кажутся настолько очевидными, что перестаёшь обращать на них внимание и видеть исключения из общих правил. И поэтому очень важно смотреть на систему с разных сторон: как менеджер по продукту, как аналитик, как программист, как пользователь системы. Попробуйте, и ваши продукты будут великолепны! Как у нас :).
Время - это бесконечная величина. Представлять бесконечную величину конечными величинами должен тот, кто поставляет данные на вход виджету. Вопрос тут вовсе не в постановке задачи, а в неправильной подаче данных виджету. Направление стрелки - это не то что должно заботить виджет. Ему вообще без разницы направление, у него может быть циферблат наоборот. В общем виноват не пулемет, из которого стреляли по воробьям.
ОтветитьУдалитьВот могу поспорить, что писал программист ;). Правильно? Просто очень характерное замечание, которое я практически в тех же словах слышал от своих ребят.
УдалитьНа мой взгляд, это просто попытка "закопать проблему", сказав "а у меня всё работает". Не должно меня заботить, что всё работает у программиста. Мне важно, что с этим пользователь работать не может.
Вот представьте, я - пользователь. У меня есть виджет, который принимает значения секунд от 0 до 59. О чём мне заботиться? Я могу получить это значение вызовом getSeconds(). Я что, должен написать свою обёртку в сто строк, чтобы удовлетворить изысканные требования вашего виджета к входным данным? Да я сам за это время такой же напишу!
Ещё раз, может быть не уловлен основной смысл статьи: модель, взятая программистами за основу, реализована безупречно. И действительно, с точки зрения программистов всё работает. Но вдруг оказывается, что, если её примерять на реальную жизнь, она оказывается как минимум странной. Именно об этом я в первом пункте и написал.
Программисты не могут не уходить в абстракции - это их работа. Но проблема в том, что очень часто эти абстракции становятся для них важнее, чем изначальный объект, который мы моделируем, постепенно его замещая.
Да, кстати, решение-то очень простое. Если циферблат круглый, надо просто добавить возможность анимации "через 0".
Неужели такая небольшая ошибка в недоделанном компоненте послужила толчком к написанию этой статьи ?
ОтветитьУдалитьДа :). Она просто очень показательна. Потому что с точки зрения разработчика всё работает отлично, а с точки зрения пользователя ничего не работает.
УдалитьИ при этому ни одной ошибки в реализации не допущено и всё сделано именно так, как планировалось.
Cразу вопрос. А у них в рамках этого проекта не было бага с тем, что когда часы показывают 16:30 часовая стрелка находится точно между 4 и 5, а то запросто может оказаться на 4 или на 5 заранее ;).
ОтветитьУдалитьP.S.
Часы конечно да. Но вот если бы заданием было написать Минигру с вращением из какой нить казуальной игры(ввод кода на сейфе, ввод времени на часах, мазайка из нескольких вращающихся дисков, и прочие диски с шестеренками), то там такие перлы программистические бывают, что картина Сальвадора становится как раз в тему.
Вот как раз промежуточным положением стрелок можно озаботиться пользователю...
УдалитьА по поводу шестерёнок - это да. Мы, кстати, как раз и делаем движок для всяких "вращающихся дисков с шестерёнками". То, что называется Gauges. Часы - это просто один из вариантов, собранный на той же базе "запчастей".
Так чему же удивляться если компонент еще "недоделанный". ;-)
ОтветитьУдалитьИграться надо уже с готовым продуктом, а то что вы пытались работать с недоделаным компонентом, я бы назвал это тестированием.
Зря вы так. Тестирование неготового продукта - это отличный способ сэкономить кучу времени и отловить ошибки на первых стадиях. Вообще, "есть слона по частям" - фундамент, например, любого agile. Кстати, фича с анимацией на тот момент уже была закрыта.
УдалитьА вообще, я не говорю, что программисты делают ошибки.
Я говорю, что у программистов и пользователей разные модели поведения в голове, которые в результате ведут к непониманию:
Пользователь: У меня ваши часы не работают
Программист: У меня всё отлично работает, проблема на вашей стороне
И, в общем-то, каждый из них прав со своей точки зрения.
Я ничего не имею против тестирования, без него никуда. Если только сам заказчик от него не отказывается.
УдалитьА в том что у програмиста сформировалась не там модель поведения, не всегда виноват програмист.
Должны быть специальные люди: ПМ, тимлидер, (может еще кто-то другой), которые должны мысль клиента доносить до разработчика.
Безусловно! Об этом и пытаюсь сказать.
УдалитьИзвините, но ваши программисты - или дети, или сферические программисты в вакууме. Написать часы, которые не идут - это надо уметь. И не надо говорить про ТЗ, в котором этого нет. Любой несферический программист должен нормально относиться к спецификациям, в которых написано не все, а некоторые вещи просто подразумеваются.
ОтветитьУдалить"Он мыслит не только интерфейсами, классами и методами, но и объектами предметной области" - это не про идеального программиста, а про нормального. Может я и не прав, но я, как программист, пишу не код, а продукт для пользователя. Код - всего лишь средство создания продукта, а хороший структурированный код с интерфейсами и всем прочим - всего лишь средство уменьшить затраты на написание и поддержку продукта.
Хотя нет - не верю в программистов-детей. Видимо у вас все слишком формализованно, и задача программиста сводится не к тому самому написанию продукта, а к реализации классов и интерфейсов, которые ему нарисовал кто-то старший.
УдалитьЯ бы извинил, если бы вы сказали, что я не умею ставить задачу или неправильно использовал компонент или ещё чего-нибудь в том же духе, извинил бы. За программистов не извиню, даже не надейтесь.
УдалитьС другой стороны - я сам виноват, что весь контекст не передал. Мы пишем платформу для создания абсолютно произвольного виджета путём сборки из составных частей. Т.е. всё основано на более-менее абстрактных спидометрах-тахометрах и прочих переключателях. И, соответственно, писался некий абстрактный движок для визуализации таких объектов. Пока всё было абстрактно, всё было великолепно, а когда дошли до конкретики, как раз и обнаружились интересные особенности.