Добавление REST поведения в класс с фляжкой, случай для чертежей?

Я имею дело с питоновым приложением, которое состоит из нескольких распределенных легких компонентов, которые обмениваются данными, используя RabbitMQ и Kombu.

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

Теперь у меня есть добавленное требование, что каждый компонент должен иметь базовый REST/HTML интерфейс. Идея в том, что вы направляете свой браузер на работающий компонент и получаете информацию в реальном времени о том, что он в данный момент делает (какие сообщения он обрабатывает, использование процессора, информация о состоянии, журнал и т.д.)

Он должен быть легковесным, так что после некоторых исследований я остановился на Flask (но открыт для предложений). В псевдокоде это означает взятие:

class Component:
   Queue A
   Queue B
   ...
   def setup(..):
     # connect to the broker & other initialization

   def start(..):
     # start the event loop and wait for work  

   def handle_msg_on_A(self,msg):
     # dispatch a msg to a handler depending on the msg type

   def handle_msg_on_B(self,msg):
     ...

   ...

и добавление ряда методов просмотра:

   @app.route('/')
   def web_ui(self):
      # render to a template

   @app.route('/state')
   def get_state(self):
      # REST method to return some internal state info as JSON

   ...

Однако, прикрепление веб-интерфейса к такому классу, как этот, нарушает принципы SOLID и приводит к проблемам с наследованием (подкласс может захотеть отобразить больше/менее подробную информацию). Декораторы не наследуются, поэтому каждый метод просмотра должен быть явно переопределен и переделан. Может быть, использование mixin + reflection может как-то сработать, но это кажется хакерским.

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

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

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

11
задан dgorissen 31 August 2011 в 12:27
поделиться