Flex-Cairngorm / Hibernate - бессмысленна ли стратегия получения EAGER? - PullRequest
1 голос
/ 26 мая 2011

Я постараюсь быть как можно более кратким. Я использую Flex / Hibernate технологии для моего приложения. Я также использую микроархитектуру Cairngorm для Flex. Поскольку я новичок, я, вероятно, неправильно понял что-то о цели ModelLocator в Caringorm. У меня следующая проблема ...

Предположим, что у нас есть следующая модель данных:

USER  ---------------->  TOPIC  ------------->  COMMENT     
      1              M          1           M 

Пользователь может создавать множество тем, в темах может быть много комментариев и т. Д. Это довольно простая модель, например. В спящем режиме я использую стратегию извлечения EAGER для однонаправленных отношений USER-> TOPIC и TOPIC-> COMMENT (здесь нет вопроса о передовой практике и т. Д., Это просто пример проблемы).

Мой ModelLocator выглядит так:

...
public class ModelLocator  ....
{
    //private instance, private constructor, getInstance() etc...
    ...

    //app state
    public var users:ArrayCollection;
    public var selectedUser:UserVO;
    public var selectedTopic:TopicVO;
}

Поскольку я использую готовую выборку, я могу «пройти» по всему графу объектов на моем клиенте Flex, не обращаясь к базе данных. Это нормально, если мне не нужно вставлять, обновлять или удалять некоторые экземпляры домена. Но когда это происходит, возникают проблемы с синхронизацией.

Например, если я хочу показать детали о каком-либо пользователе из некоторого UserListView, когда пользователь (актер) выберет этого пользователя в списке, я возьму выбранный индекс в UserList, получу элемент от пользователей ArrayCollection в ModelLocator по выбранному индексу и показать детали о выбранном пользователе.

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

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

Мой вопрос : это хороший способ использования ModelLocator в Cairngorm? Мне кажется, что из-за упомянутого извлечения EAGER как-то бессмысленно. В случае использования EAGER синхронизация на клиенте Flex может стать большой проблемой. Должен ли я всегда обращаться к базе данных, чтобы манипулировать моделью моего домена?

EDIT: Кажется, я не достаточно ясно выразился. Простите за это.

Хорошо, я также использую Spring в технологическом стеке и шаблон DTO (DVO) с сериализатором flex / spring (de), но я просто хотел остаться в стороне, потому что я пытаюсь указать, как вы остаетесь синхронизированными с состояние базы данных в вашем приложении Flex. Я даже не упоминаю многопользовательский сценарий и тему опроса / рассылки, которая, возможно, является моим решением, потому что я использую стандартный механизм запроса-ответа. Я не предоставил какой-то конкретный код, потому что это кажется мне концептуальной проблемой, и я использую стандартные термины Cairngorm, чтобы объяснить псевдо-имена, которые я использую для имен классов, имен переменных и т. Д.

Я попытаюсь снова «упростить»: у вас есть flex-клиент для администрирования вышеупомянутого домена (CRUD для каждого из классов домена), у вас есть ListOfUsersView (показывает список пользователей с основной информацией о их), UserDetailsView (показывает сведения о пользователе и список пользовательских тем с возможностью удаления для каждой темы), InsertNewUserTopicView (форма для вставки новой темы) и т. д.

Каждое из представлений , отображающее некоторую информацию, синхронизировано с переменными состояния ModelLocator , например:

ListOfUsersView ------binded to------> users:ArrayCollection in ModelLocator
UserDetailsView ------binded to------> selectedUser:UserVO in ModelLocator 
etc.

Просмотр состояния перехода выглядит так:

ListOfUsersView----detailsClick---->UserDetailsView---insertTopic--->InsertTopicView

Поэтому, когда я нажимаю кнопку "Детали" в ListOfUsersView, в моей логике я получаю индекс выбранной строки в ListOfUsers, после чего я принимаю объект UserVO из users : ArrayCollection в ModelLocator по указанному индексу, после этого i устанавливает этот объект UserVO в качестве selectedUser : UserVO в ModelLocator, а после этого i меняет состояние просмотра на UserDetailsView (показывает пользователя детали и selectedUser.topics), который синхронизируется с selectedUser: UserVO в ModelLocator.

Теперь я нажимаю «Вставить новую тему» ​​ кнопку на UserDetailsView, что приводит к форме InsertTopicView . Я ввожу некоторые данные, нажимаю «Сохранить тему» ​​ (после успешного сохранения снова отображается UserDetailsView) и возникает проблема .

Из-за моих EAGER-подобранных объектов я не попал в базу данных в упомянутых переходах, и из-за этого есть два места , о которых мне нужно беспокоиться, когда вставить новую тему для выбранного пользователя: один экземпляр selectedUser объект в пользователях: ArrayCollection (потому что моя логика выбирает пользователей из этой коллекции и показывает их в UserDetailsView), и секунда - selectedUser: UserVO (для синхронизации UserDetailsView, который появляется после успешной операции сохранения).

Итак, снова мой вопрос возникает ... Если я нажму на базу данных при каждом переходе, должен ли я перезагрузить пользователей: ArrayCollection и selectedUser: UserVO после сохранения, чтобы синхронизировать состояние базы данных с клиентом flex, если я возьму сохраненную тему и на клиенте сторона, не обращаясь к базе данных, программно пропустить все места, которые мне нужно обновить или ...?

Мне кажется, что EAGER-подобный объект с их ассоциациями не очень хорошая идея. Я ошибся?

Или, чтобы снова «упростить» :), что вы должны сделать в упомянутом сценарии? Итак, вам нужно обработать нажатие на кнопку «Сохранить тему», и что теперь ...?

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

Ответы [ 3 ]

4 голосов
/ 26 мая 2011

С моей точки зрения, дело не в самом режиме извлечения, а во взаимодействии клиент / сервер.Исходя из предыдущего опыта работы с ним, я наконец-то обнаружил некоторые недостатки использования чисто доменных объектов (особенно с активной загрузкой) для взаимодействия клиент-сервер:

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

Я думаю, что могут быть и другие причины, чтобы не использовать чистые доменные объекты, особенно при активном извлечении.

Я предлагаю вам ввести слой Mapper (или Assembler) для преобразования ваших доменных объектов в объекты передачи данных, также называемые DTO.Таким образом, каждый запрос к вашему сервисному уровню будет получать данные из вашей DAO или Active Record, а затем преобразовывать их в соответствующий DTO, используя соответствующий Mapper.Таким образом, вы можете получить список пользователей без личных данных и запросить некоторые дополнительные данные пользователя с помощью отдельного запроса.

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

Таким образом, вы можете избежать многих проблем на стороне клиента, которые вы описали.

Для слоя Mapper вы можете использовать Библиотека Dozer или создайте свои собственные облегченные сопоставители.

Надеюсь, что это поможет!

РЕДАКТИРОВАТЬ Как насчет ваших данных, я бы предпочел получить список пользователей с необходимыми отображаемыми полями, такими как firstимя и фамилия (для отображения в списке).Произнесите список SimpleUserRepresentationDTO.

Затем, если пользователь запрашивает данные пользователя для редактирования, вы запрашиваете UserDetailsDTO для этого пользователя и заполняете им поля selectedUser в модели.То же самое касается тем.

Единственная проблема - отображение списка пользователей после редактирования пользовательских данных.Вы можете:

  • Запросить весь список еще раз.Преимущество в том, что вы можете отображать изменения, выполненные другими пользователями.Но если список слишком длинный, может быть очень неэффективно каждый раз запрашивать всех пользователей, даже если они SimpleUserRepresentationDTO с минимальными данными.
  • Когда вы получаете успех с сервера при сохранении пользовательских данных, вы можете найти соответствующиепользователя в списке пользователей модели и замените измененные данные там.
0 голосов
/ 27 мая 2011

Посмотрите на проект "dpHibernate".Он реализует «ленивую загрузку» на клиенте Flex.

0 голосов
/ 26 мая 2011

Сказать по правде, нет хорошего способа использования Cairngorm.Это дерьмо рамки.

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

Что касается фреймворков, я рекомендую вам взглянуть на RobotLegs или Петрушка .

...