DDD и асинхронные репозитории

Мы работаем над многофункциональным клиентом (написанным на Flex), который подключен к серверной части Java, используя как RMI, так и JMS. Я думал о реализации клиента в стиле DDD, чтобы у него были репозитории для операций CRUD с объектами домена.

Однако проблема в том, что вся внутренняя коммуникация происходит асинхронно, и у меня нет возможности заставить клиента ждать, чтобы продолжить, пока он не получит ответ. Это означает, что на низком уровне я могу вызвать метод удаленного объекта и получить AsyncToken в качестве возвращаемого значения. Затем я могу прослушивать события в asynctoken, чтобы узнать, прошел ли вызов или нет. Однако это нарушает основную идею репозитория, чтобы скрыть технические детали от клиента.

Думаю, может быть 2 варианта:

  1. иметь методы в репозитории, возвращающие asynctoken, что мне кажется беспорядочным решением
  2. пусть методы возвращают пустую коллекцию (например, для findAll), которая будет заполнена при получении ответа.

У обоих есть свои плюсы и минусы, и я хотел бы услышать ваш отзыв, ребята.

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


person Christophe Herreman    schedule 07.10.2008    source источник


Ответы (3)


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

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

  1. Прикрепите прослушиватель событий для настраиваемого события, которое будет вызывать ваш «код результата публикации / ошибки»
  2. Сделайте асинхронный вызов
  3. Обработка результата / ошибки
  4. Отправьте настраиваемое событие для запуска вашего слушателя из # 1

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

person cliff.meyers    schedule 29.11.2008

Я бы рекомендовал вернуть AsyncToken, поскольку возвращать пустую коллекцию просто неправильно.

В случае, когда вы возвращаете данные из кеша, верните CompletedAsyncToken (: AsyncToken), который автоматически запускает событие COMPLETE с данными всякий раз, когда событие COMPLETE подписано (и затем удаляет обработчик).

public class CompleteAsyncToken : AsyncToken
{
    public function CompleteAsyncToken(data : Object)
    {
        super(data);
    }

    public override addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false) : void
    {
        super.addEventListener(type, listener, useCapture, priority, useWeakReference);

        if (type == Event.COMPLETE)
        {
            // Don't just execute listener as EventDispatcher is not that simple
            super.dispatchCompleteEvent();
            super.removeEventListener(type, listener);
        }
    }
person Richard Szalay    schedule 21.10.2008
comment
Только что нашел это, и это было мне полезно, поэтому я подумал, что добавлю к нему. Я полагаю, вы также захотите переопределить addResponder(responder:IResponder) и вызвать responder.result(some empty result object) для любого зарегистрированного респондента. - person Ocelot20; 04.10.2013

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

person Richard Dorman    schedule 21.10.2008