1

我会尽量简洁。我正在为我的应用程序使用Flex/Hibernate技术。我还为 Flex 使用Cairngorm微架构。因为我是初学者,所以我可能误解了 Caringorm 的 ModelLocator 目的。我有以下问题...

假设我们有下一个数据模型:

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 中获取选定的索引,从选定索引处的 ModelLocator 中的用户 ArrayCollection 获取元素并显示有关选定的详细信息用户。

当我想插入新用户时,好的,我将该用户保存在数据库中,并在 IResponder 结果方法中将该用户添加到 ModelLocator.users ArrayCollection 中。

但是,当我想为某个用户添加新主题时,如果我仍然想使用 EAGER 获取的便利,我需要再次重新加载用户列表......并将主题添加到选定的用户......如果用户在一些其他位置(间接),我也需要在那里插入主题。更新更糟糕。在那种情况下,我什至需要写一些逻辑......

我的问题:这是在 Cairngorm 中使用 ModelLocator 的好方法吗?在我看来,由于提到,EAGER fetching 在某种程度上是毫无意义的。在使用 EAGER fetching 的情况下,Flex 客户端上的同步可能会成为大问题。我应该总是点击数据库来操作我的域模型吗?

编辑: 似乎我没有让自己足够清楚。对不起。

好的,我在技术堆栈中也使用 Spring 和带有 flex/spring (de)serializer 的 DTO(DVO) 模式,但我只是想远离它,因为我试图指出你如何与数据库状态保持同步你的弹性应用程序。我什至没有提到多用户场景和轮询/推送主题,这也许是我的解决方案,因为我使用标准的请求-响应机制。我没有提供一些具体的代码,因为这对我来说似乎是概念性的问题,我使用标准的 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 对象:ModelLocator 中提到的索引处的ArrayCollection,之后我将该 UserVO 对象设置为 selectedUser :UserVO 在 ModelLocator 中,然后我将视图状态更改为 UserDetailsView(它显示用户详细信息和 selectedUser.topics),它与 ModelLocator 中的 selectedUser:UserVO 同步。

现在,我单击UserDetailsView 上的“插入新主题” 按钮,从而生成 InsertTopicView表单。我输入一些数据,点击“保存主题”(保存成功后,再次显示UserDetailsView)出现问题

由于我 EAGER-ly 获取的对象,我没有在提到的转换中访问数据库,因此在为选定用户插入新主题时我需要关注两个地方:一个是用户中selectedUser对象的实例:ArrayCollection(因为我的逻辑从该集合中选择用户并在 UserDetailsView 中显示它们),第二个是selectedUser:UserVO(为了同步成功保存操作后的 UserDetailsView)。

所以,我的问题又出现了......我是否应该在每次转换中都点击数据库,我是否应该在保存后重新加载 users:ArrayCollection 和 selectedUser:UserVO 以便与 flex 客户端同步数据库状态,我是否应该在客户端保存主题,而不访问数据库,以编程方式传递我需要更新的所有地方或......?

在我看来,EAGER-ly 获取对象及其关联并不是一个好主意。我错了吗?

或者,再次“简化”:),在上述情况下您应该怎么做?所以,你需要处理点击“保存主题”按钮,现在是什么......?

再一次,我真的试图尽可能地解释这一点,因为我对此感到困惑。所以,请原谅我的长篇大论。

4

3 回答 3

4

从我的角度来看,重点不在于获取模式本身,而在于客户端/服务器交互。根据我之前的经验,我终于发现了使用纯域对象(尤其是急切获取)进行客户端/服务器交互的一些缺点:

  • 您可能必须传递所有子集合,而无需在客户端使用它们。在您的情况下,您很可能不会为您从服务器获得的所有用户显示主题和评论。最喜欢的情况是您需要显示用户列表,然后显示所选用户之一的主题,然后显示所选主题之一的评论。但是在当前的实现中,即使不需要显示,您也会收到所有主题和评论。您很可能会在一次查询中收到所有数据库。
  • 另一个问题是获取所有字段(电子邮件、地址、密码、信用卡号等)的所有用户数据(或一些其他数据)可能非常不安全。

我认为可能有其他原因不使用纯域对象,尤其是急切获取。

我建议您引入一些 Mapper(或 Assembler)层来将您的域对象转换为 Data Transfer Objects aka DTO。因此,对您的服务层的每个查询都会从您的 DAO 或 Active Record 接收数据,然后使用相应的 Mapper 将其转换为相应的 DTO。因此,您可以在没有私人数据的情况下获取用户列表,并使用单独的查询来查询一些额外的用户详细信息。

在客户端,您可以直接使用这些 DTO 或将它们转换为客户端域对象。您可以在您的 Cairngorm 响应程序中执行此操作。

这样,您可以避免您描述的许多客户端问题。

对于 Mapper 层,您可以使用Dozer 库或创建自己的轻量级映射器。

希望这可以帮助!

编辑 关于您的详细信息,我希望获得包含必要可显示字段(如名字和姓氏)的用户列表(以显示在列表中)。说一个列表SimpleUserRepresentationDTO

然后,如果用户请求用户详细信息以编辑您UserDetailsDTO对该用户的请求并selectedUser用它填写模型中的游览字段。主题也是如此。

唯一的问题是在用户详细信息编辑后显示用户列表。你可以:

  • 再次请求整个列表。优点是您可以显示其他用户执行的更改。但是如果列表太长,每次查询所有用户可能是非常无效的,即使他们的SimpleUserRepresentationDTO数据很少。
  • 当您从服务器获得用户详细信息保存成功时,您可以在模型的用户列表中找到相应的用户并在那里替换更改的详细信息。
于 2011-05-26T19:13:38.610 回答
0

查看“dpHibernate”项目。它在 Flex 客户端上实现“延迟加载”。

于 2011-05-26T21:42:29.933 回答
0

实话告诉你,Cairngorm 没有好办法。这是一个垃圾框架。

我不太确定您急切获取的确切含义(或者您的问题到底是什么),但无论如何,它仍然是一种请求/响应类型的交易,除非您是没有做正确的事;在这种情况下,我看不到您的代码。

至于框架,我建议你看看RobotLegsParsley

于 2011-05-26T18:37:06.523 回答