Динамический маршрутизатор и управляющие сообщения - PullRequest
1 голос
/ 26 февраля 2011

Система, над которой я работаю, использует что-то вроде шаблона динамического маршрутизатора + dep.injection, а именно:

  1. Объект маршрутизатора использует config для создания экземпляров объектов модуля.Модули независимы и могут быть множественными.
  2. Экземпляр объекта маршрутизатора внедряется в конструктор модуля в зависимости и используется как ссылка / указатель API (вероятно, не имеет значения для вопроса, но здесь для ясности)
  3. модули используют API для добавления правил, которые связывают шаблоны ввода с конкретными методами модуля
  4. Маршрутизатор получает входные данные, проверяет их по набору правил и вызывает методы модуля, соответствующие
  5. Результатысобранный маршрутизатором и переданный в выходной процессор

Конструктор модуля:

class module {
    public function __construct(&$router) {
        $router->addRoute('some-input-pattern', array($this, 'someMethod'));
    }

    public function someMethod() {
         return 'some arbitrary result';
    }
}

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

Например, бывают случаи, когда модуль должен инициировать событие или исключение, которое должно обрабатываться самим модулем.Он может возникать в любом модульном методе и должен обрабатываться определенным методом.(Наличие множества блоков try / catch в каждом методе кажется неправильным, и единственная «точка входа», которая может обработать любое исключение, находится вне модуля и в маршрутизаторе. Выдает модуль, обрабатывает модуль, но только маршрутизатор можетна самом деле ловит. Звучит неправильно.)

class module {
    public function __construct(&$router) {
        ...
        $router->addExceptionHandler('dbTableNotFoundException', 
                                     array($this, 'installSchema'));
    }
 }

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

   public function someMethod(){
         ...
         throw routerRestartException('special-input');
   }

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

   public function someMethod(){
         ...
         throw humanEyesException("You can't do that!");
   }

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

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

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

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

РЕДАКТИРОВАТЬ

Мысль на этом пути: один из способов улучшить ситуацию, отсоединив обработчик исключений в модуле от маршрутизатора, может использовать шаблон Observer для пользовательских исключений:

public function __construct(&$router){
    ...
    dbTableNotFoundException::addObserver(array($this, 'installSchema'));
}

1 Ответ

0 голосов
/ 28 февраля 2011

Чтобы позволить модулям реагировать на другие модули и события API, я бы использовал шаблон Observer.Ваш API может предоставить несколько наблюдаемых предметов (это могут быть классы, если API может предоставить процедуры отмены регистрации и уведомления для каждого наблюдаемого субъекта)

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