Сложность кода IMHO можно значительно уменьшить, переосмыслив взаимодействие с пользователем.

Принцип единой ответственности - это общий принцип программирования, который можно применять в программировании где угодно. Я считаю, что это неукоснительно соблюдается при написании backend services. Но когда дело доходит до frontend компонентов, мы много раз пытаемся объединить обязанности и построить тяжелые компоненты.

Это повторяющаяся картина, которую я постоянно наблюдаю.

  • Приложения постепенно растут с появлением новых функций
  • Становится обременительным добавлять новые функции поверх существующих.

Примеры сценариев:

  • Приложение, управляемое данными, сконцентрированное на табличном компоненте
  • Приложение для планирования, основанное на компоненте календаря

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

Компоненты пользовательского интерфейса

В мире многоразовых компонентов пользовательского интерфейса сильно вложенные компоненты увеличивают сложность кода по мере развития приложений. Здесь мы не говорим о вложенности DOM. Мы говорим о сильно вложенных бизнес-обязанностях. Составление компонентов и поддержка компонентов более высокого порядка имеет полный смысл. Но иногда мы теряем эту границу и начинаем строить сильно связанные тяжелые компоненты. Сигналы, чтобы понять это:

  • Есть ли многие бизнес-функции внутри одного MasterComponent?
  • Тратит ли команда больше времени на то, чтобы стать экспертом в использовании MasterComponent или сделать его SuperMasterComponent, который может достичь более серьезных целей?
  • Является ли бизнес-функция простой, но включение ее в MasterComponent со всеми другими зависимостями делает ее такой сложной?

Компонент таблицы, который управляет приложением, управляемым данными

Допустим, у нас есть онлайн-приложение для корзины покупок. Нам нравится иметь таблицу данных для детализации данных.

Функции, которые мы хотели бы иметь

  • Просмотр заказов и их основных деталей
  • Просматривайте заказы с подробной информацией о продукте, чтобы мы могли проанализировать
  • Просматривайте заказы в зависимости от статуса доставки, доставлены ли они / в процессе / отменены и т. Д.
  • Просматривайте заказы с платежными реквизитами, чтобы мы могли анализировать платежные данные
  • Просматривайте заказы с данными о клиентах, чтобы мы могли анализировать информацию о клиентах
  • Просматривайте заказы с помощью shipTo деталей, чтобы мы могли анализировать обслуживаемые нами местоположения

Одна таблица, которая выполняет все вышеперечисленное

Конечно, все вышеперечисленное можно реализовать в одной таблице с библиотеками типа ag-grid. Обратите внимание, как потрясающе это выглядит с таким детальным контролем над данными.

Так почему бы не купить / не создать компонент с обширной таблицей данных, который может все?

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

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

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

  • Команда начинает добавлять функции - слой за слоем поверх компонента таблицы с открытым исходным кодом.
  • Функции могут пересекаться / конфликтовать друг с другом, вызывая разные потребности
  • Нарушение функциональности теперь может привести к каскадному отказу других функций.
  • Добавляя любую новую функцию, команда тратит больше времени на понимание того, что уже происходит в этих потоках, чем на то, что нужно сделать для новой функции. Это тормозит развитие
  • Через несколько месяцев все в команде будут уклоняться от рефакторинга / очистки кода, потому что все они верят, что происходит слишком много вещей, и не хотят нарушать текущую стабильность.
  • Производительность Backend API (ов) медленно снижается, а сложность возрастает. Возникают более сложные оптимизации, которые в будущем сможет поддерживать только меньшее количество членов команды.
  • Команда пытается внедрить новые функции, внося минимальные изменения в существующие потоки, иногда не задумываясь, если мы сделаем это заново, нуждается ли этот бизнес-поток в такой сложности.
  • Мертвый код / ​​неиспользуемый код начинает расти, так как некоторые области частично очищаются, а остальное остается, поскольку это не останавливает выполнение приложения.

Как мы можем решить эту проблему лучше с помощью принципа единой ответственности

Один из подходов к уменьшению ответственности компонента (или к созданию легковесного компонента) заключается в передаче управления другим компонентам для выполнения другой ответственности.

Передача управления другим компонентам

Большинство из нас, возможно, уже знакомы со следующими примерами. Обычно их называют разным юзабилити. Но есть огромное преимущество с точки зрения сложности кода, поскольку они разделяют обязанности на разные потоки.

Обратите внимание на приведенную ниже таблицу, в которой разделены детали строки и строки.

  • Ответственность за строку заключается только в том, чтобы получить необходимые данные.
  • Если щелкнуть строку для получения подробной информации, он просто передаст управление совершенно новому компоненту, который позаботится о том, что необходимо сделать.
  • Напротив, мы могли бы достичь того же потока с помощью группы по столбцу и вложенной таблицы. Но это все усложнит.
  1. Ошибка во вложенной таблице нарушит представление родительской таблицы.
  2. Исправление ошибки в родительской таблице или добавление функции в родительскую таблицу необходимо для обеспечения целостности функций вложенной таблицы.
  3. При извлечении данных нам нужно решить, будем ли мы выполнять предварительную выборку вложенных данных или по запросу.
  4. Если у нас есть сортировка по родительской таблице, необходимо убедиться, что представление вложенной таблицы не нарушено
  5. Если нам нужно иметь сортировку по дочерней таблице, необходимо убедиться, что родительская таблица стабильна.
  6. Что делать, если у вложенной дочерней таблицы есть дочерний элемент? В этом случае повторите все вышеуказанные проверки.

Использование модели или нескольких моделей

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

Контекстные действия

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

Несколько представлений для одних и тех же данных

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

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

Мы могли бы уместить текущие активы, детали транзакций, налоговые расчеты, данные о прибылях и убытках и т. Д. В одной таблице. Ух ты. Судя по опыту пользователей, я мог осуществить все, что хотел, в одном месте. Но в основном как пользователь я не прихожу к одному экрану с 25 целями.

Предоставляя разные представления, которые, в свою очередь, имеют одни и те же базовые данные, представленные в этом конкретном контексте, мы делаем потоки более легкими.

Доверие и надежность

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

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

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

Отправляя пользователей в разные потоки, мы обеспечиваем им прозрачность и возможность сопереживать приложению (как существу). Если что-то пойдет не так в одном потоке, они могут посочувствовать, скажем, потоки A, B, C стабильны, а потоки D и F нестабильны.

Читать далее

Резюме

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

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

Принцип единой ответственности может сделать

  • разработка интерфейса более стабильная и надежная
  • Тестирование (ручное / автоматическое) становится проще, поскольку не нужно проверять комбинацию сценариев.
  • Это помогает избежать каскадных сбоев в работе. Если что-то сломается, сломается только эта функциональность.
  • Снижает риск при непрерывной доставке. Даже если что-то сломается, легче примириться с этой областью приложения и как можно скорее развернуть исправление.

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