Lex Kravetski (lex_kravetski) wrote,
Lex Kravetski
lex_kravetski

Categories:

Не думай о секундах свысока

 
Зачем знать географию, когда есть извозчики?
(краткое содержание фрагмента диалога,
«Недоросль», Фонвизин)

 

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

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

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

Юное дарование, оно же как думает: откуда я могу знать, что нужно пользователю? У меня есть мощный алгоритм, а пользователь пусть задаст все нужные ему параметры. В этом гибкость. Не надо лишать пользователя гибкости. Юные дарования вообще очень часто говорят о гибкости.

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

Что вышло в результате? Дорога вместо часа заняла двое суток, из которых 90% времени была потрачена на подбор параметров, а ещё 9% на исправление ошибок при их выборе. Стало ли быстрее? Нет. Стало гораздо медленнее. С большой вероятностью клиент вообще послал таксиста в баню и пошёл искать вменяемого таксиста.

Так оно и есть, при использовании чего либо, пользователь знает нюансы используемого хуже, чем его разработчик. Нюансы, конечно, знать весьма полезно. Однако полезно оно, когда альтернативой является плевание в потолок или просмотр новостей по первому каналу. В ряде же случаев пользователь на деле является разработчиком более сложной вещи. Клиент таксиста мог быть академиком, который ехал на постановку эксперимента века и таксист своим «неламерским» подходом потратил ценное время академика, в ином случае бы потраченное на эксперимент. Пресловутая гибкость в случае с такси академику нафиг не сдалась. Ему надо было просто попасть в свой институт. Пусть не самым идеальным способом, а просто одним из наиболее быстрых – таксист ведь в среднем действительно знает более быстрый способ, нежели его клиент.

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

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

Например, видеомагнитофоны умеют отображать время на дисплее. Это не главная их особенность, но коль уж время отображается, его надо как-то выставлять. Для выставления времени следует включить телевизор, включить видеомагнитофон, войти в меню, выбрать один из пунктов, выбрать один из подпунктов и только после этого крутить циферки. На том же уровне иерархии, кстати, находятся настройки, которые мне вообще ничего не говорят. Например, «ИКМ». Я до сих пор не знаю, что это такое. И даже не особо хочу знать. Странно, однако настройка, которой, уверен, пользовался максимум один процент владельцев видеомагнитофона, находится так же глубоко, как установка часов. И всё бы было ничего: зашёл один раз в настройки, что-то там покрутил, выставил время и всё, больше туда не ходишь. Однако часы, сволочи, отстают. Или спешат. И ещё они перестают идти, а то и вообще сбрасываются при выключении электричества. Поэтому установка часов не такая уж редкая процедура. Почему же их так сложно устанавливать?

Помнится, раньше для получения сигнала с видеомагнитофона следовало настроить телевизор на определённый канал и переключаться на него при каждом просмотре видео. Потом разработчики догадались, что видеомагнитофон всё-таки наверно может как-то сообщить телевизору, что его уже смотрят. Работает всё это, правда, не в любой паре телевизор-видеомагнитофон, а в рамках одного производителя. Но хоть так. Теперь следующий вопрос: включённый видеомагнитофон без включённого телевизора смысла не имеет. Почему бы тогда видеомагнитофону вместо того, чтобы ограничиваться простым переводом телевизора на нужный канал (реально, конечно, в нужный режим), не включать телевизор при своём, видеомагнитофонном включении? Это не тонны времени экономит – секунды, однако таких вот мелочей целая уйма.

Особенно ярко это проявляется при работе на компьютере, а совсем ослепительно – при использовании чужого кода. Тут гибкость, любимая юными дарованиями особенно неограничена. Так, например, для конвертирования DVD в divX следует воспользоваться пятью приложениями. Очевидный же бред. Даже если закрыть глаза на неуловимый дух пиратства, заключённый в данном процессе.

А знаете, какие параметры надо задать для пересжатия из divX в divX же? Например, надо задать битрейт. Кто готов хотя бы примерно оценить необходимую для видео величину битрейта? Ещё следует сказать, в сколько проходов (pass) конвертировать фильм. Кроме того, в настройках фигурирует некоторая «квантизация». Она может принимать значения «H.263», «H.263 Optimized», «MPEG-2» и «MPEG-2 custom». Меня впечатляет, да.

Справедливости ради в более поздних версиях кодека разработчики всё-таки добавили пресеты. Однако же их название и предназначение не так, чтобы интуитивно понятно. Если «для мобильного телефона» – туда-сюда, то вот «для домашнего кинотеатра»... И всё-таки лучше хотя бы так.

Если кто-то имел дело с конвертированием звука в mp3, то он мог заметить, что сей процесс идёт куда как лучше, нежели конвертирование видео. По сути достаточно выбрать один из пресетов, которые довольно хорошо и подробно описаны. И несмотря на то, что каждый параметр сжатия можно изменить в отдельности, обычно это не требуется, поскольку разработчики уже подобрали параметры одним из наиболее оптимальных способов. Допускаю, можно подобрать лучше, однако у разработчиков на многочисленные тесты куда как больше времени, нежели у пользователей. Пользователю надо знать примерное соотношения размера результата и его «субъективное» качество в каждом пресете. Всё. Нюансы сжатия подбирают специалисты. Хотя нюансов, повторюсь, немало. Но в среднем разработчики подберут их лучше.

Как можно было сделать с ковертацией видео? Так, как уже сделали. Программа «Auto Gordian Knot» для конвертирования любого видео в формат divX или xVid просит полтора параметра – размер конечного файла и (по желанию) битрейт для аудио. Всё. (Не вдаваясь в нюансы скажу, что по сути эта программа просто в определённой последовательности вызывает те самые пять приложений с заранее подобранными настройками) 

Сторонники гибкости на этом месте возопят: как же так, вас лишают контроля над процессом!!! Хрен знает, чего там эта умная программа за вас додумает!!! Отвечаю. Выдаваемый «негибкой программой результат» ощутимо превосходит (временами на субъективные порядки) результаты, достигнутые при помощи «гибких» программ. Огромное количество валяющихся повсюду divX-фильмов пожаты очень хреново. В том смысле, что при том же размере видеосигнал там просто убит нафиг. Зато всё было гибко.

Надо понимать, что ни один пользователь не будет долго и пристально высчитывать настройки для каждого отдельного фильма. Особенно если учесть время, требуемое на конвертирование даже небольшого фрагмента этого фильма. Он, как и в случае с mp3, однажды выберет набор настроек, которые его устраивают, и будет использовать их в дальнейшем. Ещё лучше будет, если эти настройки выберут специалисты, которые в деталях знают собственный продукт. У них для этого ощутимо больше и знаний, и средств, и времени. Пользователю же нужно просто несколько вариантов с разными соотношениями критических параметров (для аудио это – размер результата и его субъективное качество).

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

Другой пример. Надо было выполнить некоторые операции при помощи OpenOffice (это такой бесплатный аналог Microsoft Office). Однако управлять им необходимо было программно. При помощи некоторого API. Операции были предельно простыми: запустить приложение, открыть в нём таблицу из файла, кое-что прочитать из ячеек, кое-что в них записать, сохранить файл, закрыть приложение. Выяснилось, что для открытия документа следует написать два десятка строк совершенно неочевидного кода. Создать туеву хучу непонятных объектов, которые нужны были только для создания других объектов. Выставить множество параметров. И так далее. Возникает вопрос: какой процент использующих внешний API OpenOffice делает что-то, кроме открытия/сохранения файлов и простейшей их модификации? Думаю, процента два-три. Остальным нужно примерно то, что описано. Почему же тогда API не позволяет достичь такой распространённой цели вызовом одной команды на каждое действие? Ответ очевиден: для гибкости.

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

Особенно наглядно это проявляется в разговорах на тему величия С++.

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

Зато, ЗАТО, многие пишущие на С++ считают себя настоящими мастерами. Потому что им, в отличие от ненастоящих мастеров, нельзя не думать каждую секунду о самых низкоуровневых нюансах своей программы. Если во многих других языках, специальные знания применяются только в критичных местах, то С++ требует применять их непрерывно. Из этого проистекает мега-гибкость. Которая компенсирует недостаток полезных средств и неудобство использования. Если ты можешь залезть в память, то зачем тебе какие-то там аннотации?

Каждый разработчик на С++ почитает за честь разработать свой собственный, самый оптимальный, самый удобный в использовании вариант списка, строки, хэш-карты, потока, сортировки и всего такого прочего. На разработку смысловых частей, конечно, времени остаётся гораздо меньше, да и появляется необходимость постоянно конвертировать один список в другой (поскольку разработчик внешней библиотеки тоже ведь сделал свой самый лучший список и свою самую лучшую строку), что время тоже не экономит. Но ядрёнть! Зато каждая библиотека гибка по самое небалуйся. С её помощью можно сделать что угодно, за исключением разве что одного: быстро достичь наиболее распространённой цели.

И это почему-то повод для гордости. Физик, например, задачу по нерелятивистской кинематике будет решать при помощи уравнений кинематики. Хотя он может в совершенстве знать уравнения Шредингера и Лагранжа, все известные способы решения всех известных их частных случаев и даже несколько ещё неизвестных. Но вот программист, применяющий для каждой задачи средства, соответствующие уровню этой задачи, у юных гуру вызывает неудержимое чувство их собственного величия. Юным гуру кажется, что это он по незнанию делает. Вот они-то знают, а вот он – нет. Да ещё и, дурачок, разрабатывает свои системы для чайников. А не как они – для пары-тройки своих элитарных коллег.

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

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

Вообще описание правильного подхода, точнее даже его принципа можно уложить в одно предложение:

 

Ресурсы, потраченные пользователем на решение задачи, должны быть обратно пропорциональны распространённости этой задачи в контексте данной системы.

 

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

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

Общее правило достижения выделенного жирным достойно аналогичного же выделения:

 

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

 

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

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

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

Зато можно отлично выпендриться и блеснуть своей элитарностью.

Tags: программирование, философия
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 120 comments
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →
Previous
← Ctrl ← Alt
Next
Ctrl → Alt →