Pull to refresh

Паттерн «VIP сервис»

Reading time4 min
Views7.9K
В предыдущей статье мы рассмотрели маленький паттерн для упрощения кода пользователей сервисов, в этой статье мы рассмотрим особый вид сервиса. Данный паттерн применяется в архитектурах имеющих слои, если рассматриваемая архитектура не имеет слоев, то паттерн может не иметь нужного эффекта либо быть вообще вредным.

Архитектурные слои
К сожалению на хабре нет статей описывающих что такое слои, но снаружи есть статья хабраюзера primepix

Паттерн не привязан к языкам программирования.

Update: Добавил пример из реальной практики.

Картинка для привлечения внимания:




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

Но в какой то момент возникает идея или требование в одной из светлых голов дизайнеров\инвесторов\креативных директоров или артистов (нужное подчеркнуть). Эта идея не ложится в текущую архитектуру. Это не обязательно может быть идея как новая функциональность, это может быть, например, поддержка кастомного функционала\режима одного из поставщиков промежуточного софта которое дает какое либо преимущество, например техническое.

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

Второе решение, если позволяет ситуация, в рабочем порядке пересмотр архитектуры и если необходимо, перепроектирование.

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

Проброс функциональности:


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

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

Инкапсуляция проброса:


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

Пример из реальной практики
Проект ММО игры. Кодобаза около 3000 файлов C#. Клиент написан на C#, для рендера использовался OGRE (C++).

Фрагмент архитектуры клиента


Самый нижний слой «Render» это реализация рендера вместе с реализациями различных эффектов (анимационные сцены, частицы) и объектов сцены с поддержкой анимации (скелетная, морф). Все что касалось отображения в том или ином виде было реализовано в этом слое.

Слой «Render facade» являлся интерфейсом(фасадом) к рендеру и содержал все обертки нативного кода для использования в C#.

Слой «Scene graph» представлял собой место для симуляции объектов и их взаимодействия.

Слой «Logic» симулировал объекты и отображал логику на объекты симуляции.

В этом фрагменте опущены другие системы, которые находились в этих слоях, например нет UI (который тоже представлял собой C# обертки для C++).

Объекты в слое сцен графа представляли собой простейшие объекты, которые содержали позицию и ориентацию. Поддерживали иерархию а так же управление абстрактной анимацией через идентификаторы (грубо говоря старт и стоп по id).

После очередного всплеска креативности, дизайнерам понадобилось менять цвета материалов в зависимости от логики в рантайме. Мотивация была следующая — «Некогда объяснять, сделай нам смену цвета материалов!», впрочем в геймдеве это обычная практика (смайлик).

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

Проброс функциональности (показан красным цветом)


Времени на обдумывание и тем более на эксперименты не хватало, поэтому было решено временно оформить эту функциональность как независимый сервис. При этом не затрагивался даже интерфейс объекта, некая реализация метода расширения (extension methods) только в глобальном контексте.

Реализация VIP сервиса


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

Со временем в этом сервисе появлялись и исчезали различные методы для очень хитрых виджетов и другие проблемные решения.

А функциональность материалов была удалена из сервиса после реализации полноценного анимационного графа с поддержкой всех аспектов визуализации. И смену материалов дизайнер указывал как часть анимации.



Плюсы:
  • Функциональность доступна сразу
  • Выигрыш времени на проработку правильного решения
  • Технические долги не расползаются по системе
  • Быстрый доступ ко всем долгам системы (для оценки проблем архитектуры)
  • Возможны решения целого класса проблем, так как решения конкретных проблем откладываются
  • Прямой выигрыш если в функциональности отпадет надобность


Минусы:
  • Паттерн не везде применим


Всем спасибо за понимание!
Tags:
Hubs:
Total votes 13: ↑7 and ↓6+1
Comments11

Articles