Vaadin:设计模式

30

我目前正在开发三个Vaadin应用程序,但感觉似乎少了点什么。之前我使用的是Spring MVC,那里的架构清晰且解耦,你将服务注入到控制器中,不会将控制器与UI耦合等。

现在在Vaadin中有所不同。如果有任何Vaadin专家,请让我问几个问题:

问题1:

  • 是否可以直接将服务(或DAO)注入到UI组件中?
  • 示例:负责在电子邮件应用程序中显示联系人的组件(ContactWidget,基于VerticalLayout和Links),需要显示联系人。是否可以直接向此UI元素注入contactRepository?

问题2:

  • 对于大量UI组件来说,都需要引用主应用程序,因为它们需要访问一些全局数据或在主应用程序类上调用全局方法
  • 示例:弹出组件具有按钮,该按钮打开新窗口,应为应用程序中主窗口的子窗口。因此,弹出组件必须引用主应用程序。

问题3:

  • UI组件之间的依赖关系可能会变得非常复杂。这里可能没有太多可以做的,但有时候感觉窗口依赖于列表,而列表又依赖于此弹出框……你懂的,看起来紧密耦合。

我希望在我的代码变成意大利面条之前尽可能了解Vaadin的良好设计,因此任何建议、经验和最佳实践都将不胜感激。

2个回答

16

我们在编程中使用了MVVM模式(也称为Fowler的PresentationModel),效果非常好。他的文档有点老,但是作为一个很好的起点。

在你阅读完之后,我的回答可能会更有意义。

  1. 不要。将你的服务注入到ViewModel中。ViewModel将是一个外观(可以封装适配器、装饰器、缓存和任何其他你决定需要的模式)

  2. 我没有看到问题,但我们有一个类似于你所描述的情况。我们使用Guava的EventBus在解耦的组件之间进行通信。通过这种方式,如果你需要弹出一个新窗口,你可以: eventBus.post(new NewWindowRequest(theComponent)) 然后你的主应用程序可以订阅同一事件,然后弹出窗口。

  3. MVVM和谨慎使用EventBus可以帮助解决问题。此外,Vaadin的BeanItem和ObjectProperty可以用于传播更改,因为它们是Vaadin内置的观察者/数据绑定模式的一部分。

最近我做了一场有关MVC、MVP和MVVM的演讲。这个示例代码可以帮助你理解从MVC到MVVM的转变。它是用JavaScript编写的,但足够简单,我相信大多数人都能够理解。欢迎您提出任何反馈意见。


谢谢Dusty。最终我选择了手工制作的MVP(非常轻量级)和基于Guava的eventBus的事件传播。尽管Vaadin没有坚实的MVP框架(虽然有数十个beta/alpha/experimental版本),但我对这个决定感到非常满意。 - Xorty
是的,尽管已经存在很长时间,但它没有足够的追随者来获得其他技术所拥有的工程师的喜爱。大多数使用它的人都在寻找最简单的解决方案,或者像我们一样,没有足够的时间记录我们正在做的事情。手工建造是一个非常好的选择。概念是重要的部分,大多数MVC/MVP/MVVM框架只是为了确保你在画线条。如果你有纪律性,它们通常不是必需的。 - Dusty J

9

Vaadin是一个很棒的软件,你肯定不希望最终代码变得混乱。不管怎样,一切取决于你。

回答 1

不,无论使用哪个框架,紧密耦合都是不好的。你的例子(ContactWidget)描述了一个列表的自定义实现。它可以作为表格进行呈现,也可以加入附加信息。我将使用表格示例,因为它更复杂,更灵活(您可以构建具有高级表格组件和适当数据绑定的整个应用程序)。

Vaadin定义了遵循众所周知的MVC模式的高级数据模型。有三个嵌套层:容器(container),项目(item),属性(property)(还定义了属性查看器和编辑器)。Vaadin书籍提供了一个很好的类比:电子表格应用程序。因此,容器、项目和属性将对应于表格、行和单元格。易于想象--易于理解。最后,ItemContainer将揭示其本质,你将明白这是任何良好且灵活的基于Vaadin的体系结构的关键合同。我建议浏览Vaadin书籍以获取所有其他细节:

您还可以查看任何PagedTable插件后面的容器实现,以更好地了解。请从ArrayContainer https://vaadin.com/directory#addon/array-container开始,它会为您简化很多操作。

回答 2

传递主应用程序引用似乎不是一个好的解决方案。您已经注意到Application实例表示会话,但最好为您定义某种SessionContext协议(仍然可以由您的应用程序实现)。可以定义静态方法来提供对相关SessionContext实例的透明访问。在底层,它可以使用ThreadLocal变量http://docs.oracle.com/javase/7/docs/api/java/lang/ThreadLocal.html。这样,您就可以摆脱所有寄生参数传递。

回答 3

设计您的层次结构时要非常小心。不要自己触发重新绘制,使用Refresher。关注整个体系结构。

最后,Vaadin易于使用,因此在更改主代码库之前,可以尝试一些微小的PoCs和演示。

如建议所述,您还可以尝试MVVM https://vaadin.com/directory#addon/bambi-mvvm


1
谢谢你的回答,我看了一下bambi-mvvm - 看起来非常不错,但是它还不够完整、未经测试和处于beta版本。我发现大多数与MVVM/MVP Vaadin相关的东西也是如此 :( - Xorty
不客气。Vaadin还比较年轻,或者更准确地说是相对年轻 :) 就我个人而言,我更喜欢自己实现Container、Container.Indexed等功能来获取分页和其他一些特性。 - Renat Gilmanov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接