JSF支持bean结构(最佳实践)

时间:2009-04-14 01:51:58

标签: java jsf

我希望在这篇文章中,我可以得到人们对JSF页面和支持bean之间接口的最佳实践的看法。

我永远无法解决的一件事是我的支持豆的结构。此外,我从未找到关于这个主题的好文章。

哪些属性属于哪个支持bean?何时适合向给定bean添加更多属性,而不是创建新bean并将属性添加到其中?对于简单的应用程序,考虑到将一个bean注入另一个bean所涉及的复杂性,为整个页面只有一个支持bean是否有意义?支持bean是否应该包含任何实际的业务逻辑,还是应该严格包含数据?

随意回答这些问题和其他可能出现的问题。


至于减少JSF页面和支持bean之间的耦合,我从不允许JSF页面访问任何支持bean属性的属性。例如,我从不允许以下内容:

<h:outputText value="#{myBean.anObject.anObjectProperty}" />

我总是要求:

<h:outputText value="#{myBean.theObjectProperty}" />

支持bean值为:

public String getTheObjectProperty()
{
    return anObject.getAnObjectProperty();
}

当我遍历集合时,我使用包装类来避免向下钻取到数据表中的对象。

总的来说,这种方法对我来说是“正确的”。它避免了视图和数据之间的任何耦合。如果我错了,请纠正我。

6 个答案:

答案 0 :(得分:143)

您可能需要查看此内容:making distinctions between different kinds of JSF managed beans

以下是Neil Griffin在上文中定义的不同bean类型的描述:

  • Model Managed-Bean 通常会话范围。这种类型的托管bean参与MVC设计模式的“模型”关注。当你看到“模型”这个词时 - 想想数据。 JSF模型bean应该是遵循JavaBean设计模式的POJO,其中getter / setter封装属性。模型bean最常见的用例是数据库实体,或者只是表示数据库查询结果集中的一组行。
  • 支持Managed-Bean 通常请求范围。这种类型的托管bean参与MVC设计模式的“视图”关注。 backing-bean的目的是支持UI逻辑,并且与Facef组合中的JSF视图或JSF表单具有1 :: 1的关系。虽然它通常具有带有关联getter / setter的JavaBean样式属性,但它们是View的属性 - 而不是底层应用程序数据模型的属性。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。
  • Controller Managed-Bean 通常请求范围。这种类型的托管bean参与MVC设计模式的“Controller”关注。控制器bean的目的是执行某种业务逻辑并将导航结果返回给JSF导航处理程序。 JSF控制器bean通常具有JSF操作方法(而不是actionListener方法)。
  • 支持Managed-Bean 通常是会话或应用程序范围。这种类型的bean“支持”MVC设计模式的“View”关注中的一个或多个视图。典型的用例是向JSF h:selectOneMenu下拉列表提供一个ArrayList,它出现在多个JSF视图中。如果下拉列表中的数据特定于用户,则bean将保留在会话范围内。但是,如果数据适用于所有用户(例如省份的下拉列表),那么bean将保留在应用程序范围内,以便可以为所有用户缓存它。
  • Utility Managed-Bean 通常是应用程序范围。这种类型的bean为一个或多个JSF视图提供了某种类型的“实用程序”功能。一个很好的例子可能是FileUpload bean,它可以在多个Web应用程序中重用。

答案 1 :(得分:14)

好问题。当我搬到JSF时,我遇到了同样的困境。这真的取决于你的应用程序。我来自Java EE世界,所以我建议尽可能少地使用后台bean中的业务逻辑。如果逻辑与页面的呈现完全相关,那么可以将它放在支持bean中。

我相信JSF的(众多)优势之一实际上是您可以直接在托管bean上公开域对象。因此,我强烈建议使用<:outputText value="#{myBean.anObject.anObjectProperty}" />方法,否则您最终会为自己手动曝光每个属性做太多工作。此外,如果封装了所有属性,插入或更新数据时会有点混乱。在某些情况下,单个域对象可能不够用。在这些情况下,我在将它暴露在bean上之前准备一个 ValueObject

编辑:实际上,如果要封装要公开的每个对象属性,我建议您将UI组件绑定到辅助bean,然后将内容直接注入组件的值

就bean结构而言,我的转折点是当我强行忽略所有关于构建Web应用程序的知识并开始将其视为GUI应用程序时。 JSF模仿Swing很多,因此开发Swing应用程序的最佳实践大多也适用于构建JSF应用程序。

答案 2 :(得分:4)

我可能不会回答你的每一个问题,因为很少看起来完全依赖于个案。

  • 在你的支持bean中有一个业务逻辑很好。这取决于你来自哪里。如果您正在练习域驱动设计,那么您将很想将业务逻辑包含在支持bean中,或者也可能是持久性逻辑。他们争辩说为什么这么愚蠢的对象。对象不仅应该携带状态,还应该携带行为。另一方面,如果您考虑传统的Java EE工作方式,您可能会感觉在支持bean中有数据,也可能是您的实体bean,以及某些会话bean中的其他业务和持久性逻辑。那也没关系。

  • 在整个页面中使用单个支持bean是完全没问题的。我没有看到任何问题。这看起来可能不正确,但这取决于具体情况。

  • 您的其他问题更多地取决于您手头的情况。我更喜欢在这里进行域驱动,可能适合向现有域添加属性或者为此创建新bean。哪个更适合。我认为没有任何银弹。

  • 哪些属性属于哪个辅助bean。那么,它不依赖于域对象吗?或者问题可能不那么明确。

此外,在您给定的代码示例中,我没有看到任何巨大的好处。

答案 3 :(得分:4)

我不需要每页只保留一个支持bean。它取决于功能,但大多数时候我每页有一个bean,因为大多数时候一个页面处理一个功能。例如,在页面上,我有一个注册链接(我将与RegisterBean链接)和一个购物篮链接(ShoopingBasketBean)。

我确实使用了这个&lt;:outputText value =“#{myBean.anObject.anObjectProperty}”/&gt;因为我通常会将bean作为保存数据对象的动作bean。我不想在我的支持bean中编写一个包装器来访问我的数据对象的属性。

答案 4 :(得分:4)

我认为对你的支持bean最重要的是分离他们的逻辑。如果您有CMS系统的首页,我会认为将每段代码放入一个bean是不好的做法,因为:

  1. 豆最终会变得很大
  2. 如果他们正在对登录页面进行故障排除,那么其他人更容易找到他们所寻找的内容,如果他们可以轻松查找loginBean.java文件。
  3. 有时候你有一小部分功能明显不同于你的代码的其余部分,通过分离这个我想你会让你自己更容易重新开发/扩展这个代码到更大的东西,当你已经有一个很好的结构良好的豆。
  4. 如果/当你必须做这样的声明时,有一个大的bean,要做到这一切,将使它更依赖于内存MyBigBean bigBean = new MyBigBean();而不是使用您实际需要的funksjonality做LoginBean loginBean = new LoginBean(); (如果我错了,请纠正我???)
  5. 在我看来,分离你的bean就像分开你的方法一样。你不想要一个运行超过100行的大方法,而是用处理其特定任务的新方法将其拆分。
  6. 请记住,除了你之外,很可能还有其他人需要处理你的JSF项目。
  7. <小时/> 至于耦合,我不认为这是一个麻烦的问题,允许你的JSF页面访问你的backbean中的对象属性。这是JSF中内置的支持,实际上只是让它更容易阅读和构建imo。你已经完全分离了MVC逻辑。通过这样做,您可以在自己的后端使用getter和setter来节省大量的行。例如,我有一个非常大的对象由Web服务给我,我需要在我的演示文稿中使用一些属性。如果我要为每个属性制作一个getter / setter,我的bean将扩展至少100行变量和方法来获得这些属性。通过使用内置的JSF功能,我的时间和宝贵的代码行都得以幸免。

    即使问题已标记为已回答,也只需要2美分。

答案 5 :(得分:0)

我喜欢在没有View的情况下测试业务代码,因此我将BackingBeans视为从View到Model代码的接口。我从来没有在BackingBean中放置任何规则或进程。该代码进入服务或帮助程序,允许重用。

如果您使用验证器,请将它们从BackingBean中取出并从验证方法中引用它们。

如果您访问DAO以填充选择,无线电,复选框,请始终使用BackingBean。

相信我!您可以将JavaBean注入BackingBean,但尝试将BackingBean注入另一个。您将很快处于维护和理解代码的过程中。