Дублирование кода или создание универсальных компонентов?
Исходная задача - проекты исполнителей и заказчиков. Представьте ситуацию. У вас есть 3 роли - Заказчик, Исполнитель, Администратор, Все 3 роли имеют свой профиль, а также работают с некой сущностью проект.
Исходная задача - проекты исполнителей и заказчиков.
Представьте ситуацию.
У вас есть 3 роли - Заказчик, Исполнитель, Администратор,
Все 3 роли имеют свой профиль, а также работают с некой сущностью проект.
Вам нужно выводить для каждой роли Список доступных ему проектов, страницу проекта, а также дать возможность редактирования своих данных.
Как вы сделаете разбиение по компонентам.
Самое простое, что напрашивается - реализовать для всех ролей:
- editProfile - форма изменения профиля
- project - форма проекта
- projects - таблица проектов.
Всего 3 компонента, которые все обслуживают. Красота.
Если думать с точки зрения того, кто создает это и пытается уменьшить свои трудозатраты, то возможно.
С точки зрения того, кто это будет потом поддерживать и развивать - это ужасное решение.
Почему это решение плохое:
- Каждая роль будет иметь свои нюансы (например, Заказчик и Админ могут редактировать некоторые поля проекта). Это создаст некоторые ветвления бизнес-логики.
- Созданные ветвления и нюансы доступа создают риски по несанкционированному доступу (в код где-то закралась ошибка, и Заказчик получает какую-то функцию Админа в форме проекта).
- При изменениях нужно распутывать весь клубок с учетом работы всех ролей на этой форме. К примеру, хотим добавить новое поле (например, заметки Заказчика по проекту) - значит сразу должны учесть эту бизнес-логику для других ролей, которых вообще никаким боком она не касается. Но у них доступ есть к этой форме, а значит это нужно обработать.
- Любое изменение в такой монстр-форме - это обязательное тестирование под всеми ролями, т.к. изменение для одной роли может повлечь изменение для другой роли.
- Зачастую для Заказчика, Исполнителя есть правки дизайна, стилистики (т.к. это обложка), и они совершенно не нужны админу.
Как я предлагаю решать подобную задачу
Важно сразу учитывать, как будет развиваться компонент. Например, попробовать предсказать развитие формы проекта для Заказчика - что там может добавиться, что измениться.
Что очевидно - формы для Заказчика, Исполнителя и Администратора будут развиваться совершенно по-разному.
Если бы у нас была еще роль Модератор, то скорее всего можно предположить, что форма будет примерно одинаково развиваться с Администратором.
Предлагаю сделать такое разбиение:
- Редактирование профиля Админа;
- Редактирование профиля Заказчика;
- Редактирование профиля Исполнителя;
- Таблица проектов Админа;
- Таблица проектов Заказчика;
- Таблица проектов Исполнителя;
- Форма проекта Админа;
- Форма проекта Заказчика;
- Форма проекта Исполнителя.
Изначально это кажется избыточным и сложным. Но именно это рождает простоту дальнейшей поддержки и развития проекта.
Даже если какие-то формы на начальном этапе очень похожи (например, профиль Заказчика и Исполнителя), в будущем они "разойдутся" в разные стороны.
Какие минусы этого решения: надо создать больше компонентов.
А теперь про плюсы (по аналогии со списком выше):
- Компоненты будут максимально простыми, они учитывают только одну роль, минимум ветвлений + мы изначально знаем, кто пришел, его права и обязанности относительно сущности.
- В компоненте мы сразу можем идентифицировать пользователя и проверять доступ к конкретным объектам. Ниже риски ошибок доступа.
- Изменения касаются только одной роли - проще разобраться, что менять.
- При изменениях нет риска задеть что-то для других ролей. Меняем для админа - можем быть уверенными, что ничего не упадет у Заказчика.
- Разметка формы под конкретную роль - меньше кода и заточка именно под эту роль без учета других ролей.
И что? Теперь создавать N ролей * K форм компонентов?
В данном примере да, но в общем случае нужно рассуждать исходя именно из будущих изменений и функций блока для конкретной роли.
В каких случаях делать компонент X отдельно для ролей A и B:
- роли A и B кардинально разные. Имеют разные доступы и в целом в системе имеют разные цели;
- роли A и B будут по-разному развиваться (к примеру, роль Заказчик и Агентство-Заказчик - в целом похожи, но функционал второй роли явно будет в будущем шире);
- бизнес-логика по работе компонента для ролей A и B будет разная.
В каких случаях можно делать один компонент на двоих:
- роли очень похожи относительно этого компонента (Модератор, Админ);
- роли будут в дальнейшем развиваться похожим образом в отношении этого компонента;
- доступ ролей в целом похож, и не будет больших рисков даже в случае несанкционного доступа одной роли.
В целом, вопрос только в будущих причинах изменения компонента. Например, в системе бух захотел изменить что-то в своем интерфейсе. А это затрагивает почему-то формы в кабинете Клиента - это не очень хорошо. В идеале это должно влиять только на формы буха и не трогать "чужие" компоненты.
Важно. Не стоит думать, что, если вы создали 2 очень похожих формы для разных ролей, которые будут развиваться по-разному - это дублирование кода. Это не разные объекты в системе, и у каждой свой путь развития. В целом, и человек на ранней стадии не сильно отличается от других животных, но это не значит, что это одно и то же. Стол и стул - дублирование? Нет. Они чем-то похожи, но у них разное назначение, и развились они исторически по-разному. Вполне возможно в допотопные времена они изначально были очень похожи, а потом постепенно стали изменяться под возникающие потребности.
Особенности подхода по созданию отдельных компонентов под роль
Разделение на компоненты не должно вызывать дублирование кода в плане типовых действий. Их можно вынести в отдельные функции или хранимые процедуры (если мы говорим про SQL).
Читайте подробнее про качество кода программы.
Также некие дополнительные возможности для отдельных ролей можно просто добавлять как доп компонент. К примеру, форма проекта для Модератора и Администратора может быть одна. Но у Админа есть на форме еще дополнительные формы и таблицы для более плотного управления (и эти таблицы, формы уже доступны только Админу).
Заключение
Подобный подход значительно упростит поддержку системы.
Универсальный подход только в теории выглядит красиво, на практике поддерживать такой проект с кучей универсальных монстр-компонентом - это хождение по минному полю.
Данное решение критически важно для проекта, т.к. именно оно определяет в дальнейшем насколько сложно будет поддерживать проект, насколько хрупким оно будет.
В некоторых случаях сверх универсальные компоненты после ряда правок в рамках сопровождения в итоге приходят к тому, что их надо переписывать - компонент стал очень сложным и трудно поддерживаемым.
Принимайте правильные решения, и это упростит ваш продукт, а значит уменьшит расходы на сопровождение в перспективе.
- Шаг 1. Создать концепт проекта
- Шаг 2. Получить оценку бюджета (КП)
- Шаг 3. Заключить договор
- Шаг 4. Создать совместно техническое задание
- Шаг 5. Поэтапная реализация проекта