
Разработчики тоже пользователи - часть 1
5 рекомендаций по повышению удобства использования пользовательского интерфейса и API
В предыдущей статье мы рассмотрели важность удобства использования пользовательского интерфейса и API, а также то, что рекомендации по удобству использования пользовательского интерфейса также могут быть применены к API. Посмотрите здесь.
В этой статье мы обсудим первые 5 рекомендаций по удобству использования:
- Видимость состояния системы
- Матч между системой и реальным миром
- Пользовательский контроль и свобода
- Системность и стандарты
- Предотвращение ошибок
1. Видимость состояния системы
Система должна держать пользователей в курсе происходящего посредством соответствующей обратной связи в разумные сроки.
Пользовательский интерфейс: когда пользователь инициирует действие, которое занимает больше времени, проинформируйте его о ходе выполнения. По возможности предпочитайте индикатор выполнения загружающемуся изображению, уведомление о загрузке или загрузке с процентами. Пользователь должен знать, чего он ждет и сколько времени это может занять.

API: API должен предоставлять способы запроса текущего состояния. Например, класс AnimatedVectorDrawable предоставляет способ проверить, запущена ли анимация или нет:
boolean isAnimationRunning = avd.isRunning();
API может предоставлять обратную связь в виде механизмов обратного вызова, позволяя пользователям API знать, когда объекты меняют состояние - например, уведомление о том, когда анимация начинается и заканчивается. Объекты AnimatedVectorDrawable позволяют зарегистрировать для этой цели AnimationCallback.
2. Соответствие системы и реального мира
Приложение должно говорить на языке пользователя с использованием фраз и понятий, знакомых пользователю, а не системно-ориентированных терминов.
Именование классов и методов должно соответствовать ожиданиям пользователей.
API: при поиске класса в новом API пользователь не имеет определенной отправной точки и полагается либо на предыдущий опыт работы с аналогичными API, либо на общие концепции, относящиеся к домену API. Например, при использовании Glide или Picasso для загрузки и отображения изображения пользователь может искать метод под названием «загрузка» или «загрузка».
3. Пользовательский контроль и свобода
Предложите пользователям возможность отменить свои действия.
Пользовательский интерфейс: для действий, инициированных пользователем, при которых может возникнуть двусмысленность в том, что что-то произошло, например, удаление или архивирование электронного письма, отобразить сообщение, подтверждающее это и позволяющее пользователю отменить действие.

API-интерфейсы должны позволять прерывать или сбрасывать операции и легко возвращать API в нормальное состояние.
API: Например, Retrofit предоставляет метод Call # cancel, который пытается отменить сетевой вызов в полете или, если вызов еще не был выполнен, гарантирует, что этого никогда не будет. Если вы работаете с API NotificationManager, вы увидите, что вы можете как создавать, так и отменять уведомления.
4. Последовательность и стандарты
Пользователи вашего приложения не должны задаваться вопросом, означают ли разные слова, ситуации или действия одно и то же.
Пользовательский интерфейс: пользователи, взаимодействующие с вашим приложением, были обучены взаимодействию с другими приложениями, и они ожидают, что общие элементы взаимодействия будут выглядеть и вести себя определенным образом. Отклонение от этих соглашений открывает путь к условиям, подверженным ошибкам.
Будьте совместимы с платформой и используйте элементы управления пользовательского интерфейса, которые хорошо известны пользователям, чтобы они могли быстро их распознать и действовать в соответствии с ними. Кроме того, будьте последовательны во всем своем приложении. Используйте одни и те же слова и значки для обозначения одних и тех же вещей при использовании на нескольких экранах в вашем приложении. Например, всегда используйте один и тот же значок редактирования, когда пользователи могут редактировать несколько элементов в вашем приложении.
API: все части дизайна API должны быть согласованы.
Используйте единообразное именование методов
Рассмотрим следующий пример, где у нас есть интерфейс, который предоставляет два способа установки двух разных типов наблюдателей:
public interface MyInterface {
void registerContentObserver(ContentObserver observer);
void addDataSetObserver(DataSetObserver observer);
}
Пользователи этого интерфейса спросят себя, в чем разница между register…Observer и add…Observer. Может ли один метод допускать одновременное использование только одного наблюдателя, а другой - нескольких? Разработчикам потребуется либо внимательно прочитать документацию, либо поискать реализацию интерфейса, чтобы убедиться, что оба метода ведут себя одинаково.
private List<ContentObserver> contentObservers;
private List<DataSetObserver> dataSetObservers;
public void registerContentObserver(ContentObserver observer) {
contentObservers.add(observer);
}
public void addDataSetObserver(DataSetObserver observer){
dataSetObservers.add(observer);
}
Используйте то же имя для методов, которые делают то же самое.
Попробуйте использовать пары антонимов: получить - установить, добавить - удалить, подписаться - отказаться от подписки, показать - отклонить.
Используйте согласованный порядок параметров в методах
При перегрузке методов убедитесь, что вы сохраняете тот же порядок параметров, которые присутствуют во всех методах. В противном случае пользователи вашего API потратят больше времени на понимание различий между перегруженными методами.
void setNotificationUri( ContentResolver cr,
Uri notifyUri);
void setNotificationUri( Uri notifyUri,
ContentResolver cr,
int userHandle);
Избегайте функций с несколькими последовательными параметрами одного и того же типа
Хотя Android Studio упрощает работу с методами с несколькими последовательными параметрами одного и того же типа, ошибки упорядочивания легко сделать и их сложнее найти. Порядок параметров должен соответствовать логическому порядку параметров, где это возможно.
В качестве решения для этого вы можете использовать шаблон построителя или, для Kotlin, именованные параметры.
Методы должны иметь максимум 4 параметра.
Чем больше параметров, тем сложнее метод. Для каждого параметра пользователь должен понимать значение метода, а также отношение к другим параметрам. Это означает, что каждый дополнительный параметр приводит к экспоненциальному увеличению сложности. Если у метода более 4 параметров, рассмотрите возможность инкапсуляции некоторых из них в другие классы или использования построителей.
Возвращаемое значение влияет на сложность метода
Когда метод возвращает значение, разработчики должны знать, что это значение представляет, как его хранить и т. Д. Когда возвращаемое значение не используется, это не влияет на сложность метода.
Например, при вставке объекта в базу данных Room может возвращать как Long, так и void. Когда пользователь API хочет использовать возвращаемое значение, ему сначала нужно понять, что оно означает, а затем где его хранить. Когда значение не требуется, можно использовать метод void.
@Insert Long insertData(Data data); @Insert void insertData(Data data);
Следовательно, вы должны предпочесть возвращать значение, позволяя пользователю API решать, где ему это нужно или нет. Если вы создаете библиотеку на основе генерации кода, разрешите методы, возвращающие оба параметра.
5. Предотвращение ошибок
Создайте дизайн, который в первую очередь предотвращает возникновение проблемы.
Пользовательский интерфейс: часто пользователи отвлекаются от текущей задачи, поэтому вам следует предотвращать неосознанные ошибки, направляя пользователей, чтобы они оставались на правильном пути и имели меньше шансов ошибиться. Например, вы можете попросить их подтвердить перед разрушительными действиями или предложить хорошие настройки по умолчанию.
Например, Google Фото гарантирует, что вы не удалите альбомы по ошибке, добавив диалоговое окно подтверждения. Папка «Входящие» позволяет отложить сообщение электронной почты и предоставляет настройки по умолчанию одним щелчком мыши.

API должен направлять пользователя в правильное использование API. По возможности используйте значения по умолчанию.
API-интерфейсы должны быть простыми в использовании и трудными для злоупотребления. Помогите своим пользователям, предоставив значения по умолчанию. Например, при создании базы данных Room одно из значений по умолчанию гарантирует, что данные в базе данных сохранятся даже при увеличении версии базы данных. Это приводит к лучшему удобству использования для пользователей приложения, которое включает Room, поскольку их данные хранятся, а версии базы данных прозрачны.
Room также предоставляет метод, который может изменить это поведение: fallbackToDestructiveMigration, который уничтожает, а затем повторно создает базу данных при изменении версии, если миграция не была предоставлена.
У нас осталось еще 5 рекомендаций, в которые можно погрузиться: