DDD и асинхронные репозитории
-
05-07-2019 - |
Вопрос
Мы работаем над расширенным клиентом (написанным на Flex), который подключен к бэкэнду Java с использованием RMI и JMS. Я думал о реализации клиента в стиле DDD, чтобы у него были репозитории для операций CRUD над объектами домена.
Проблема, однако, в том, что вся внутренняя связь происходит асинхронно, и я не могу заставить клиента ждать продолжения, пока он не получит ответ. Это означает, что на низком уровне я могу вызвать метод для удаленного объекта и получить AsyncToken в качестве возвращаемого значения. Затем я могу прослушать события на asynctoken, чтобы увидеть, прошел или нет вызов. Это, однако, нарушает основную идею хранилища - скрывать технические детали от клиента.
Я думаю, что может быть 2 варианта:
<Ол>У обоих есть свои плюсы и минусы, и я хотел бы получить от вас информацию, ребята.
(продолжая, какие будут хорошие стратегии кэширования? Зависит от ситуации, я не хочу, чтобы хранилище вызывало сервер каждый раз, когда я запрашиваю у него все сущности. Как это повлияет на сигнатуру методов на хранилище.)
Решение
Flex и Flash Remoting по своей сути асинхронны, поэтому борьба с этой парадигмой доставит вам массу неприятностей. Наши делегаты службы возвращают AsyncToken из каждого метода, и у нас никогда не было проблем с ним.
Если вы хотите убедиться, что приложение не отображает новое представление или не выполняет какую-либо другую логику, пока не вернется результат / ошибка, вы можете сделать следующее:
<Ол>Имейте в виду, что каждый раз, когда вы делаете асинхронный вызов, это приводит к большому количеству раздражающего кода буфера. Я бы очень внимательно подумал, нужен ли вам синхронный путь выполнения.
Другие советы
Я бы порекомендовал вернуть 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);
}
}
Одной из стратегий было бы создание фасада перед хранилищем. Ваш клиент будет выполнять асинхронные вызовы фасада, которые, в свою очередь, будут выполнять синхронный вызов вашего хранилища. Это позволит вашему хранилищу продолжать работать синхронно, в то время как фасад управляет асинхронными аспектами вашего вызова.