JSF支持bean结构(最佳实践)
我希望在这篇文章中,我可以听取人们对JSF页面和支持bean之间接口的最佳实践的意见。
有一件我永远无法解决的事情就是我的支持豆的结构。 此外,我从来没有find关于这个问题的好文章。
哪些属性属于哪个后台bean? 什么时候给给定的bean添加更多的属性是合适的,而不是创build一个新的bean并添加属性到它上面? 对于简单的应用程序来说,考虑到将一个bean注入另一个bean所涉及的复杂性,对于整个页面只有一个支持bean是否有意义? 后台bean是否应该包含任何实际的业务逻辑,还是应该严格包含数据?
随时回答这些问题和其他可能出现的问题。
至于减lessJSF页面和后台bean之间的耦合,我绝不允许JSF页面访问任何后台bean属性的属性。 例如,我绝不允许诸如:
<h:outputText value="#{myBean.anObject.anObjectProperty}" />
我总是需要像这样的东西:
<h:outputText value="#{myBean.theObjectProperty}" />
有一个支持bean的值:
public String getTheObjectProperty() { return anObject.getAnObjectProperty(); }
当我遍历一个集合时,我使用一个包装类来避免钻入数据表中的一个对象,例如。
一般来说,这种方法对我来说是“正确的”。 它避免了视图和数据之间的任何耦合。 如果我错了,请纠正我。
您可能需要检查: 区分不同types的JSF托pipe的bean 。
下面是Neil Griffin上面的文章中定义的不同beantypes的描述:
- Model Managed-Bean : 通常是会话范围。 这种types的托pipebean参与了MVCdevise模式的“模型”关注。 当你看到“模型”这个词 – 想想DATA。 JSF模型bean应该是一个遵循JavaBeandevise模式的POJO,使用getter / setter封装属性。 模型bean最常见的用例是数据库实体,或者简单地代表数据库查询结果集中的一组行。
- 备份Managed-Bean : 通常请求范围。 这种types的托pipebean参与了MVCdevise模式的“View”关注。 支持bean的目的是支持UI逻辑,并且与JSF视图或Facelet组合中的JSF表单具有1 :: 1的关系。 虽然它通常具有与关联的getter / setter相关联的JavaBean样式的属性,但它们是View的属性 – 而不是底层的应用程序数据模型的属性。 JSF支持bean也可能有JSF actionListener和valueChangeListener方法。
- Controller Managed-Bean : 通常请求范围。 这种types的托pipebean参与了MVCdevise模式的“控制器”关注。 控制器bean的目的是执行某种业务逻辑,并将导航结果返回给JSF导航处理程序。 JSF控制器bean通常具有JSF操作方法(而不是actionListener方法)。
- 支持Managed-Bean : 通常是会话或应用程序范围。 这种types的bean在MVCdevise模式的“视图”关注中“支持”一个或多个视图。 典型的用例是将ArrayList提供给出现在多个JSF视图中的JSF h:selectOneMenu下拉列表。 如果下拉列表中的数据是用户特有的,那么这个bean将被保存在会话范围内。 但是,如果数据适用于所有用户(例如省份的下拉列表),那么bean将被保存在应用程序范围中,以便它可以被所有用户高速caching。
- 实用程序托pipeBean : 通常应用程序范围。 这种types的bean为一个或多个JSF视图提供某种“实用”function。 一个很好的例子就是可以在多个Web应用程序中重用的FileUpload bean。
伟大的问题。 当我转移到JSF时,我遭受了同样的困境。 这真的取决于你的应用程序。 我来自Java EE世界,所以我build议在后台bean中尽可能less地使用业务逻辑。 如果逻辑与页面的表示完全相关,那么可以在后台bean中使用它。
我相信JSF的(许多)优势之一实际上是可以直接在托pipebean上公开域对象的事实。 因此,我强烈build议使用<:outputText value="#{myBean.anObject.anObjectProperty}" />
方法,否则在手动暴露每个属性时,最终会为自己做太多工作。 此外,如果您封装了所有的属性,插入或更新数据将会有点麻烦。 在某些情况下,单个域对象可能不够用。 在这些情况下,我在将它公开在bean上之前准备一个ValueObject 。
编辑:其实,如果你打算封装你想公开的每个对象的属性,我会build议你,而不是绑定UI组件的支持豆,然后将内容直接注入组件的值。
就bean结构而言,我的转折点是当我强行忽略所有关于构buildWeb应用程序的知识,并开始将其作为GUI应用程序来处理。 JSF模仿Swing很多,因此开发Swing应用程序的最佳实践大多也适用于构buildJSF应用程序。
我可能不会回答你的每一个问题,因为很less有人完全依赖个案。
-
在后台bean中有一个业务逻辑是很好的。 这取决于你从哪里来。 如果您正在实践领域驱动的devise,您将被诱惑将业务逻辑包含在支持bean中,或者可能是持久化逻辑。 他们争辩说为什么这么愚蠢的对象。 对象应该不仅仅是状态而是行为。 另一方面,如果考虑传统的Java EE做事情的方式,你可能会感觉到你的后台bean中有数据,也可能是你的实体bean,以及某些会话bean中的其他业务和持久化逻辑。 这也没关系。
-
对于整个页面来说,有一个单独的支持bean是完全正确的。 我看不出有任何问题。 这看起来可能不正确,但这取决于案件。
-
你的另一个问题更依赖于你手中的情况。 我宁愿在这里进行域驱动,向现有的属性添加属性或者为其创build一个新的bean可能是合适的。 哪个更适合。 我不认为这有什么银弹。
-
哪些属性属于哪个后台bean。 那么,它不依赖于域对象? 或者可能是这个问题不是很清楚。
而且,在你给出的代码示例中,我没有看到任何巨大的好处。
我不需要每页只保留一个支持豆。 这取决于function,但大多数情况下我每页有一个bean,大多数页面处理一个function。 例如在一个页面上,我有一个注册链接(我将与RegisterBean链接)和一个购物篮链接(ShoopingBasketBean)。
我通常使用这个<:outputText value =“#{myBean.anObject.anObjectProperty}”/>,因为我通常将bean保持为保存数据对象的操作bean。 我不想在我的支持bean中写封装来访问我的数据对象的属性。
我认为你的支持豆最重要的是分开他们的逻辑。 如果你有一个CMS系统的首页,我会认为把每一段代码放到一个bean中是不好的做法,因为:
- 这个bean最终会变的很大
- 如果他们正在对login页面进行故障排除,那么其他人就可以更容易地find他们想要查找的内容,如果他们可以轻松查找loginBean.java文件。
- 有时候,你有一小部分function与代码中的其他部分截然不同,通过分离我可以想象,如果你已经有了一个好的bean,那么你可以让自己更容易重新开发/扩展这些代码,结构体。
- 如果/当你必须做这样的声明时,有1个大豆,这样做会使它更依赖于内存。MyBigBean bigBean = new MyBigBean(); 而不是通过做LoginBean实际需要的funksjonality loginBean = new LoginBean(); (纠正我,如果我在这里错了???)
- 在我看来,分离你的豆就像分离你的方法。 你不想要一个运行了100多行的大方法,而是用处理它们特定任务的新方法分割它。
- 请记住,除了你之外,很可能还有其他人不得不在你的JSF项目上工作。
至于耦合,我不认为这是一个麻烦的问题,让您的JSF页面也访问您的后台bean中的对象的属性。 这是内置到JSF中的支持,实际上它使读取和构buildimo变得更容易。 你的allready严格分离MVC逻辑。 通过这样做,你可以在你的支持者身上节省大量的获得者和制定者。 例如,我有一个非常大的Web服务给我的对象,我需要在我的演示文稿中使用一些属性。 如果我要为每个属性创build一个getter / setter,那么我的bean将会扩展至less100多行variables和方法来获取propeties。 通过使用内置的JSFfunction,我的时间和珍贵的代码行都可以省去。
只是我的2美分,即使这个问题已经被标记为回答。
我喜欢在没有View的情况下testing业务代码,所以我将BackingBeans视为从View到Model代码的接口。 我从来没有把任何规则或过程放在BackingBean中。 该代码进入服务或助手,允许重用。
如果您使用validation器,请将它们从您的BackingBean中取出,并从validation方法中引用它们。
如果你访问DAO来填充select,收音机,checkbox,那么总是使用BackingBean。
相信我!。 您可以将JavaBean注入到BackingBean中,但是尝试将BackingBean注入到另一个中。 您将很快进入维护和理解代码的精髓。
- 执行失败的任务:在Android Studio中的应用程序:compileDebugJavaWithJavac
- 使用Maven进行集成testing的最佳实践?
- 在JDBC中,当自动提交是错误的并且没有设置明确的保存点时,回滚是好的样式还是浪费?
- 为什么我不断收到'SVN:locking工作拷贝XXXX; 尝试执行“清理”?
- RestTemplate线程安全吗?
- 你应该报告exception的消息文本?
- 错误:registry项'Software \ JavaSoft \ Java Runtime Environment'\ CurrentVersion'?
- 什么额外的轮换是需要从自上而下删除2-3-4左红黑树?
- java:这是什么:[Ljava.lang.Object;?