Pull to refresh

Comments 35

Самой большой проблемой обоих подходов (UI) является страх и предубеждение российских программистов перед произвольным кодом выполняемым на клиенте… мол, как это так на клиенте мы выполняем любой код, который присылаем с сервера.

Да, да именно так. Обоим подходам уже больше 20 лет, но наши программисты до сих пор «боятся» их использовать.
Вы, наверное, хотели сказать «бэкэнд боится»?
Недавно пытался продать бэкэнду связку couchdb/pouchdb. На меня посмотрели как на сумасшедшего, мол, как так, доступ в базу с клиента.
И правильно смотрели. Доступ с клиента напрямую в БД может быть обоснован только в случае, если это изначально приложение для системной работы с базами данных (тулза разработчика). В «реальном мире» веб-приложений (и вообще клиент-серверных приложений) не принято делать бизнес-логику средствами СУБД, для этого обычно заводят отдельное звено (сервер приложений). Триггеры и хранимые процедуры правильно использовать только для поддержки консистентности персистентных моделей, а не для слоя бизнес-логики.
В том то и дело, что как такого «прямого» доступа там нет. Там отличная фоновая синхронизация с (разумеющейся) проверкой всех прав на стороне couchdb. Бизнес-логики там никакой, триггеров и хранимок никаких, это обычный key/value. Представьте, что это не «база», а «транспорт» до бэка.
Взгляните
Я видел и даже использовал. Уверен, что можно найти условия, в которых такой «транспорт» будет полезен — если и на сервере, и на клиенте это будет заинкапсулировано в бибилотеках синхронизации клиентских и серверных моделей, а логика синхронизации будет гарантировать отсутствие противоречий. Но в общем случае это не очень полезная архитектура, т.к. синхронизация моделей происходит без контроля слоя бизнес-логики, который лишь по факту УЖЕ наличия отсинхронизированных неконсистентных состояний на сервере должен будет как-то оповестить клиента и откатить транзакции и на сервере, и на клиенте.

hypers gonna hype.
Оба подхода имеют право на жизнь, но, имхо, лучше писать быстрые бэкенды.

Безусловно, но быстрые бэкенды бессильны перед плохим или медленным интернетом.

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

Вот именно для мессенджера, особенно если очередность сообщений не важна, Optimistic UI хорошо подходит. Но это как раз то исключение, которое подтверждает правило

https://console.cloud.google.com работает по Realistic UI, по сути. Должен сказать что это по началу очень непривычно, когда система принимает мой запрос, но при этом позволяет заниматься другими делами, пока он выполняется. При этом визуально только небольшой лоадер в шапке страницы и на кнопке…

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

ммм… а если на странице есть зависимые операции? Их мы получается тоже не должны дать редактировать?

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

Даже если оно окажется удачным, всё равно надо блокировать. Зависимая операция может использовать результат первого действия.

Логично. Только скорее не запретить редактирование, а запретить отправку на сервер. Тогда логично будет. Пользователь отправил одно, и пока оно отправляется он уже заполняет другое. А когда первое отправится ему даётся возможность отправить второе.

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

Ну заблокировать её нетрудно, а вот как показать связность действий тут уже немного другой вопрос.
Можно формы поставить друг под другом и стрелочками или циферками показывать последовательность, но это 100% не то. Слишком муторно и выглядеть будет не так эстетично. Ещё вариант написать на кнопке отправки "Ждём результатов предыдущего действия...". Ну или короче как-то.

Можно оставить только одну кнопку «Отправить», когда отправка предыдущих данных завершится, переместить эту кнопку под новые данные и разблокировать.
  1. Порядок сообщений в мессенджере ещё как важен. Это бывает по круче, чем расположение запятой.


  2. Не надо блокировать интерфейс. У пользователя должна быть возможность отменить лайк или исправить данные в форме не дожидаясь ответа от сервера.

По первому пункту воздержусь от комментария.


Концепция блокировки части UI не является синонимом отсутствия возможности отмена запросов — достаточно добавить в UI рядом с заблокированной кнопкой "Отправить" кнопку "Отмена".

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

Если пользователь поставил лайк, а потом его решил снять, то вам в любом случае нужно сделать 2 запроса. Блокировка инетрфейса внесёт лишь лишнее раздражение у пользователя, которому приходится сидеть и ждать пока обработается установка лайка, чтобы появилась возможность его снять. Вы поиграйтесь с примером — результат всегда ожидаемый. Кроме, разумеется, случая, когда сервер упал с ошибкой.

Упасть может не только сервер, а ещё и клиент, а точнее его соединение с интернетом.
В вашем примере нету механизма, который делает только 2 запроса, в случае дислайка. Как и говорится в статье, для того, чтобы реализовать это нужен отдельный механизм, который будет убивать один запрос и зарождать другой. Не очень удобно, согласитесь. Причём надо пришибить запрос так, чтобы он не успел отправить данные на сервер. А если долго тупит не транспорт меж юзером и сервером, а сервер? Тогда не получается, потому что будет столько запросов, сколько "закажет" юзер. А если какой-то последний не дойдёт, тогда будет интересно, потому что конечная задача не выполнена, лайк не убран, зато отправлено over 1000 запросов.

в приведённом примере первый запрос отменяется. и совершенно не важно, дошёл ли он до сервера. всё равно второй затрёт его изменения. а если не затрёт, то пользователь увидит ошибку и попробует снова. Постарайтесь думать не в терминах деиствий, а в терминах состояний. А чтобы было наглядней — предтавьте, что пользователь не лайки ставит, а наносит ядерные удары, на каждый из которых требуется по 1 часу.

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

Никакой клиентской логикой вы не защититесь от дос атаки. Банально потому, что злоумышленнику не составит труда её изменить. А пользователей не стоит считать за имбицилов.

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

Кстати, как вам ui хабра? Он ведь по сути сделан на realistic. Тут и кнопочки всякие блокируются, и сообщения не прилитают, пока они на сервере не созданы.

Бывает сбойнёт и кнопка не разблокируется. В итоге приходится перезагружать страницу, чтобы разблокировать кнопку.

А если не блокировать интерфейс, то может получиться примерно так:
Лайкнул… Хм, не не хочу, дислайкнул… Что-то не дизлайкается, надо бы ещё раз, и ещё раз {over 30} Блин, у меня же интернет сдох!
В общем, блокировка как раз таки является одним из ограничителей юзера, которые он должен видеть. Конечно же, мы хотим огородить пользователя от всей этой лабуды с запросами и ответами, но какие-то вещи от нас не зависят и их скрыть просто невозможно, и эта вещь — время отклика сервера. Как бы мы не кочевряжились, если данные не пришли, то мы не можем сказать, что они пришли. Юзер будет думать, что его документ уже отправлен и люди уже смотрят его и вникают, а он уже упал при запросе отправки на сервер.


Просто диалог с оптимистичным получается такой:


  • Я хочу отметить вот эту галку
  • Окей, уже отмечено
  • А теперь вот эту
  • Извини, но прошлая не отметилась, так что тебе придётся её отметить заново.
К сожалению, даже Realistic UI оказался не застрахованным от странных переключателей вместо понятных и привычных чекбоксов.

Этот контрол к Realistic UI явного отношения не имеет :) Обратите внимание на 3 принципа, указанных в статье; все остальное — вторично

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


А с чекбоксами я еще во время twitter bootstrap возился, пытаясь их хоть как-то привести в ту позицию, в которой хочу их видеть кроме штатного чекбокса "Запомнить меня" в окне ввода емейла/пароля

Sign up to leave a comment.

Articles