Замкнутость интерфейса

Блог Ильи Бирмана ·

Замкнутость интерфейса — это полнота и непротиворечивость правил, определяющих его состояния и переходы между ними при всех допустимых сочетаниях данных, условий и событий. Для любого допустимого сочетания данных и условий ясно, как выглядит и ведёт себя интерфейс. Например, список может быть пустым, содержать одно значение или тысячу, и мы понимаем, как они выглядят. Это состояния. В каждом состоянии определён перечень допустимых событий, включая действия пользователя, которые влияют на интерфейс, например, значения можно добавлять и удалять, и нам тоже ясно, как это всё работает. Это переходы. Самое интересное и сложное — это то, что переход должен полностью определяться состоянием и событием. Он не может зависеть от истории предыдущих состояний (если только это не буквально переход по истории состояний типа «Назад» или «Анду»). Если переход из некоторого состояния S при событии E зависит от того, попали мы в S из Q или R, то это значит, что нет никакого состояния S, а есть состояния S1 (S после Q) и S2 (S после R), и важно это осознать. Может показаться, что это какая-то заумь и вообще, какая разница. Но если не обращать внимания на это, то в интерфейсе возникают неявные состояния, в которых вид и переходы не определены. Дизайнер-то думает, что рассмотрел состояние S, да вот только это мифическое состояние, а настоящие состояния S1 и S2 он не рассмотрел. При проектировании сложного интерфейса иногда непреднамеренно возникают состояния, из которых невозможно выбраться, или до которых невозможно добраться, или до которых можно добраться только, если сразу пойти по правильному пути. Для дизайнера важно научиться видеть это. Часто бывает, что я спрашиваю, например, «А в этом случае что будет?», и дизайнер только в этот момент понимает, что такой случай вообще существует. Внимательно разбираться с замкнутостью — кропотливая работа. Обычно мы рассматривает разные состояния и переходы в контексте некоторого флоу, то есть пути пользователя. Мы рисуем экраны друг за другом и представляем, как человек проходит между ними. Нам кажется логичным, что после такого-то экрана при таком-то действии появляется сякой-то, и мы не замечаем, что в другом флоу на таком же экране при таком же действии появляется другой экран. Когда мы думаем про этот флоу и смотрим на это глазами пользователя, мы почти всегда думаем о любом состоянии в контексте предыдущих состояний, и не отдаём себе в этом отчёт. В моём примере с автодополнением отдельные решения сначала кажутся нормальным, пока не начинаешь смотреть, какие запутанные состояния и переходы они порождают. Исправление каждой возникающей неприятности создаёт исключение, усложняя систему и добавляя неприятностей. Я приводил примеры вопросов , которые помогают проверить интерфейс, но понятно, что ответы даже на все вопросы сами по себе не гарантируют замкнутость. О замкнутости следует думать как о математическом качестве. Возьмём такую теорему: «Число 60 делится на все числа». Это легко проверить: на 1 делится, на 2 делится, на 3 делится, на 4 делится. Мне продолжать? Ну на 5 делится, на 6 делится, сколько ещё примеров надо? Какое число ни возьми — на всё делится: 10, 15, 20... Так ведь? Но нет, это ничего не доказывает. Чтобы доказать теорему, нужно искать не удачные примеры в большом количестве, а саму фундаментальную причину, по которой она неизбежно верна. В данном случае такой причины нет. При проектировании интерфейса сложно требовать от дизайнеров рисования полного графа состояний и переходов. Не уверен, что делал такое хоть раз в жизни. Но всё же полезно хотя бы понять, что это такое. Полезен и опыт программирования — оно развивает интуицию на такие вещи. Смотришь на проект интерфейса, и чутьё подсказывает: что-то не то, сейчас найду дыры. И дыры находятся. Вообще, чем больше для описания интерфейса приходится придумывать частных исключений, тем больше возникает подозрений в том, что общее правило плохое или вообще не придумано.

Замкнутость интерфейса — это полнота и непротиворечивость правил, определяющих его состояния и переходы между ними при всех допустимых сочетаниях данных, условий и событий. Для любого допустимого сочетания данных и условий ясно, как выглядит и ведёт себя интерфейс. Например, список может быть пустым, содержать одно значение или тысячу, и мы понимаем, как они выглядят. Это состояния. В каждом состоянии определён перечень допустимых событий, включая действия пользователя, которые влияют на интерфейс, например, значения можно добавлять и удалять, и нам тоже ясно, как это всё работает. Это переходы. Самое интересное и сложное — это то, что переход должен полностью определяться состоянием и событием. Он не может зависеть от истории предыдущих состояний (если только это не буквально переход по истории состояний типа «Назад» или «Анду»). Если переход из некоторого состояния S при событии E зависит от того, попали мы в S из Q или R, то это значит, что нет никакого состояния S, а есть состояния S1 (S после Q) и S2 (S после R), и важно это осознать. Может показаться, что это какая-то заумь и вообще, какая разница. Но если не обращать внимания на это, то в интерфейсе возникают неявные состояния, в которых вид и переходы не определены. Дизайнер-то думает, что рассмотрел состояние S, да вот только это мифическое состояние, а настоящие состояния S1 и S2 он не рассмотрел. При проектировании сложного интерфейса иногда непреднамеренно возникают состояния, из которых невозможно выбраться, или до которых невозможно добраться, или до которых можно добраться только, если сразу пойти по правильному пути. Для дизайнера важно научиться видеть это. Часто бывает, что я спрашиваю, например, «А в этом случае что будет?», и дизайнер только в этот момент понимает, что такой случай вообще существует. Внимательно разбираться с замкнутостью — кропотливая работа. Обычно мы рассматривает разные состояния и переходы в контексте некоторого флоу, то есть пути пользователя. Мы рисуем экраны друг за другом и представляем, как человек проходит между ними. Нам кажется логичным, что после такого-то экрана при таком-то действии появляется сякой-то, и мы не замечаем, что в другом флоу на таком же экране при таком же действии появляется другой экран. Когда мы думаем про этот флоу и смотрим на это глазами пользователя, мы почти всегда думаем о любом состоянии в контексте предыдущих состояний, и не отдаём себе в этом отчёт. В моём примере с автодополнением отдельные решения сначала кажутся нормальным, пока не начинаешь смотреть, какие запутанные состояния и переходы они порождают. Исправление каждой возникающей неприятности создаёт исключение, усложняя систему и добавляя неприятностей. Я приводил примеры вопросов , которые помогают проверить интерфейс, но понятно, что ответы даже на все вопросы сами по себе не гарантируют замкнутость. О замкнутости следует думать как о математическом качестве. Возьмём такую теорему: «Число 60 делится на все числа». Это легко проверить: на 1 делится, на 2 делится, на 3 делится, на 4 делится. Мне продолжать? Ну на 5 делится, на 6 делится, сколько ещё примеров надо? Какое число ни возьми — на всё делится: 10, 15, 20... Так ведь? Но нет, это ничего не доказывает. Чтобы доказать теорему, нужно искать не удачные примеры в большом количестве, а саму фундаментальную причину, по которой она неизбежно верна. В данном случае такой причины нет. При проектировании интерфейса сложно требовать от дизайнеров рисования полного графа состояний и переходов. Не уверен, что делал такое хоть раз в жизни. Но всё же полезно хотя бы понять, что это такое. Полезен и опыт программирования — оно развивает интуицию на такие вещи. Смотришь на проект интерфейса, и чутьё подсказывает: что-то не то, сейчас найду дыры. И дыры находятся. Вообще, чем больше для описания интерфейса приходится придумывать частных исключений, тем больше возникает подозрений в том, что общее правило плохое или вообще не придумано.

Источник: Блог Ильи Бирмана