Что есть грамотный интерфейс?

Что такое "грамотный интерфейс"? Это интерфейс, который позволяет выжать из пользователя максимум производительности.

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

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

  • Интерфейс Должен быть привычным.

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

  • Интерфейс должен использовать знания и навыки, уже имеющиеся у пользователя.

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

  • Интерфейс должен быть умным.

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

  • Интерфейс должен быть догадливым.

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

  • Интерфейс должен быть удобным.

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

  • Интерфейс должен быть быстрым.

    КПД пользователя и так не очень высокий и не стоит его еще более уменьшать за счет тормознутости интерфейса. Реакция компьютера на действия пользователя должна быть максимально быстрой. Следовательно всякие фишки с анимацией окон, проявляющимися меню и прочей фигней, из-за которой пользователю приходится прерываться (пусть даже на доли секунды) - ЗЛО! Окна должны появляться молниеносно как только в них возникла необходимость и так же быстро исчезать, как только необходимость в их отображении пропала. Крутящиеся на экране песочные часы - признак плохо спроектированного интерфейса или программы в целом.

  • Интерфейс должен быть Интерфейсом!

    Главная цель интерфейса - поддерживать диалог с пользователем. Т.е. с помощью интерфейса пользователь и программа обмениваются информацией. Значит интерфейс должен давать пользователю максимум информации. Плохой пример из этой области - окно с единственной надписью "Ждите, идет расчет...". Хороший пример - окно, содержащее кроме надписи еще и "градусник" хода процесса и показывающее примерное время до завершения. Высший пилотаж - добавить к этому окну звуковой сигнал по окончании процесса.

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


Билл Гейтс покидает Microsoft.

Выступление Билла Гейтса на выставке высоких технологий «CES 2008» стало сенсацией. Глава корпорации «Microsoft» уже неоднократно использовал подмостки выставки для предсказания будущего в сфере инновационных технологий.

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

Около четырех тысяч человек собрались в отеле «Venetian Hotel's Palazzo Ballroom» в Лас Вегасе, чтобы услышать доклад главы корпорации «Microsoft» Билла Гейтса, приуроченной к ежегодной выставке высоких технологий CES 2008.

«Мое первое выступление здесь состоялось очень давно, в 1994 году, - начал Гейтс. – Это было время, когда Windows 95 делал свои первые шаги, а эпоха Интернет только зарождалась».

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

«Мы проделали огромный путь и это только начало», - подчеркнул он.

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

Поэтому продукты ведущих производителей будут ориентированны на конечного пользователя. Кроме того, многие программы станут универсальными и смогут использоваться не только на персональном компьютере, но и в Интернете, на мобильном телефоне, на экране телевизора.Глава «Microsoft» выделил три основных тенденции, которые, по его мнению, будут превалировать в будущем.

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

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

При этом передача станет возможной в любом направлении между большим кол-вом пользователей.

Третий фактор, возможности которого, по мнению Гейтса, недооценивают больше всего – это создание «естественного интерфейса».

«Символом первой цифровой эры стали мышь и клавиатура, - отметил создатель «Microsoft» – Однако уже сейчас мы развиваем новые формы взаимодействия машины и пользователя».

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

Что касается корпорации «Microsoft», она сосредоточится на разработке кроссплатформенных решений, улучшении пользовательских интерфейсов и создании новых мультимедийных сервисов, устройств ввода и систем распознавания речи.

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

Отметив, что это его последний публичный доклад, Билл Гейтс объявил о том, что в июле намерен сложить с себя полномочия руководителя «Microsoft» и вплотную заняться деятельностью своего благотворительного фонда «Bill & Melinda Gates Foundation».

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

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


Залепа №9. Microsoft друзей не признает.

Начну с цитаты из одной полезной книжки Алена И. Голуба "Правила программирования в С и С++" (речь идет именно о C++):

Цитата:

Как-то раз я видел интерфейс, в котором объект "календарь" позволял пользователю интерактивно выбирать дату, щелкая мышью на каком-либо из дней, показанных на изображении календаря. "Календарь" затем экспортирует эту дату в другие части программы, помещая ее в объект "дата", который возвращается из сообщения get_date(). Проблема здесь в том, что проектирование выполнено наизнанку. Программист мыслил структурными категориями, а не объектно-ориентированными.

При выполнении должным образом единственным видимым в других частях программы объектом был бы объект "дата". "Дата" использовала бы объект "календарь" для реализации сообщения "инициализируй_себя" (которое могло бы быть конструктором), но "календарь" бы содержался внутри "даты". Определение класса "календарь" можно было бы даже вложить в определение класса "дата". Объект "дата" также мог бы поддерживать другие инициализирующие сообщения, такие как "инициализируй_себя_от_редактируемого_ввода" или "инициализируй_себя_из_строки", но во всех случаях объект "дата" отвечает за нужное для инициализации взаимодействие с пользовательским интерфейсом. Остальная часть программы просто бы непосредственно использовала "дату"; никто, кроме "даты", даже бы не знал о существовании объекта "календарь". То есть вы бы объявили "дату" и приказали ей себя инициализировать. Затем вы можете передавать объект "дата" всюду, куда необходимо. Конечно, "дата" должна также уметь себя вывести, переслать в файл или из файла, сравнить себя с другими датами и так далее.

Другими словами, правильное проектирование в ООП - это создание классов, АБСОЛЮТНО НЕЗАВИСИМЫХ от других классов и объектов, инкапсулирующих все необходимые для работы классы внутри себя. Только такой тип проектирования позволяет создавать действительно переносимый код, который без всякой адаптации можно встроить в свою программу.

Следуя описанному выше работа с классом "дата" должна выглядеть примерно так:

Пример кода:
CDate cd = new CDate(); 
// создали объект "дата" с текущей датой внутри
cd = new CDate("15.06.2007");
// инициализировали строкой
cd = new CDate(15, 6, 2007);
// инициализировали числовыми значениями 
cd = my_date;
// инициализировали другим объектом класса CData (присваивание)

cd.SaveToFile("c:\\autoexec.bat");
// сохранили дату в файл
cd.LoadFromFile("c:\\autoexec.bat");
// прочи дату из файла

int days = cd - new CDate("28.02.2006");
// получили количество дней между датами
cd += 365;
// получили дату, на год большую исходной
int dw = cd.DayOfWeek();
// вернуло номер дня недели

cd.ShowCalendar();
// отображение календаря для ввода даты пользователем.

... ну и так далее.

Естественно, класс CDate должен быть порожден от System.Windows.Control или иметь некий другой механизм, чтобы (при необходимости) без проблем встраиваться в пользовательский интерфейс. Оцените удобство такого контрола в сравнении с предлагаемым аналогом из библиотеки .NET. Думаю, не надо доказывать, что описываемый здесь на порядок удобнее для программиста. Вот это и есть грамотное, правильное проектирование в стиле ООП.

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

Итак, упростим задачу до предела:

  • есть класс CDate, представляющий ни что иное как обычную календарную дату.
  • есть класс CCalendar, представляющий собой вспомогательное окно, отображающее календарь и принимающее ввод от юзера.

Требования к реализации:

  • 1) все операции касающиеся даты, должны выполняться в классе CDate. И это есть логично.
  • 2) класс календаря, фактически являясь окном, имеет только "оконную" функциональность. Т.е. никаких собственных вычислений дат и периодов он не делает - у нас для этого есть CDate. И это тоже есть логично.
  • 3) не забываем про инкапсуляцию, т.е. пользователь нашего класса CDate НЕ должен иметь доступ к функциям внутренней обработки. Для него предоставлен интерфейс взаимодействия в виде открытых свойств и методов, им пусть и пользуется.

Отсюда вытекают пункты:

  • 3а) класс календаря не должен быть виден пользователю. Более того, пользователь не должен даже догадываться о том, что CDate использует внутри еще что-то.
  • 3б) проект должен иметь некую "модульную" структуру, чтобы встраивание класса CDate в реальную программу было максимально простым.

Что ж, давайте немного углубимся и попробуем осмыслить, как все это будет работать.

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

Судя по первым двум пунктам, наши объекты CDate и CCalendar будут активно вызывать методы друг друга. Причем, скорее всего случится так, что календарю потребуется доступ к некоторым методам CDate, которые предназначены для внутренних механизмов самого CDate. Такое вполне вероятно.

К чему я веду? А к тому, что тут мы уперлись головой в очередной косяк C# - отсутствие в языке понятия "дружественности". :(

В C++ мы бы просто сделали класс CCalendar другом класса CDate, разрешив тем самым календарю использовать внутренние механизмы в виде вызовов защищенных методов CDate. Согласен, решение не самое элегантное, но, поскольку оба класса разрабатываются нами, а пользователи о таком "разделении труда" даже не подозревают (и соответственно не смогут, например, породить наследников от календаря), то такое решение вполне приемлемо.

Выигрыш от него на лицо: календарь может использовать скрытые возможность CDate, при этом пользователь все так же остается ограниченным рамками предоставленного нами открытого интерфейса CDate (пункт 3 выполняется в полной мере).

Что же мы имеем в шарпе?

А там мы лишний раз убеждаемся в том, что технология .NET - это технология, в которой ничего хорошего NЕТ! В данном случае, в ней НЕТ дружественности. И поэтому, чтобы открыть доступ календарю к скрытой внутренней функциональности CDate, нам придется открыть эту функциональность и для всех остальных. Подозреваю, что именно поэтому классы .NET набиты таким большим количеством лишних методов и обработчиков - мелкомягкие вступили в собственную ловушку.

Чем грозит такое "открытие внутренней функциональности" наверное объяснять не нужно: вот есть класс, вот его методы, причем ОТКРЫТЫЕ методы, но пользоваться ими нельзя, т.к. они предназначены для внутренних нужд. Гы-гы-гы! :)

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

Ладно, время покажет, может все же я зря смеюсь. Давайте лучше закончим с нашим примером.

Пункты 3а и 3б в C# так же вызывают некоторые проблемы. А именно, если распространять свой класс CDate в виде исходников, то он потянет за собой и класс CCalendar, а мы бы не хотели, чтобы пользователь знал о нем. Если же скомпоновать наш класс в сборку (assembly), то класс календаря можно сделать ненаследуемым, но при таком подходе пользователю уже не удастся сделать программу из одного exe-файла - придется тягать за собой еще и нашу сборку.

Сборки - это здорово по отношению к DLL, но убого по отношению к обычным библиотечным файлам, которые до .NET существовали в любом компилирующем языке и функции из которых встраивались прямо в exe-шник, не создавая никаких проблем. Причем, встраивалась не вся библиотека, а только функции/классы, реально использующиеся в приложении. В случае же сборок (как и в случае DLL), нам приходится тянуть за собой мегабайты сборочного барахла даже если мы используем из нее только одну функцию, размером в 300 байт. Почему майкрософт отказалась от использования библиотек объектных модулей мне лично не понятно.

Но возможно они еще вернут такую возможность. По крайней мере у меня есть повод так думать. А откуда взялась такая уверенность напишу в одном из следующих постов.


Fast: [10] [20]

Этот сайт полностью окупает себя, хотя его ТИЦ=10, а PR=2. Хотите знать, как он это делает? Хотите чтобы Ваш сайт чарез пол-часа тоже начал на полном автопилоте приносить деньги?
Регистрируйся здесь и здесь и начинай получать деньги со своего сайта!