Vaadin:设计模式 [关闭]

Posted

技术标签:

【中文标题】Vaadin:设计模式 [关闭]【英文标题】:Vaadin: Design patterns [closed] 【发布时间】:2012-09-27 16:46:28 【问题描述】:

我目前正在开发三个 Vaadin 应用程序,我真的觉得我错过了一些东西。我之前使用过 Spring MVC,架构清晰解耦,你将服务注入到控制器,而不是将控制器耦合到 UI 等等。

现在在 Vaadin,情况就不同了。所以如果有任何 Vaadin 专家,让我问你几个问题:

问题 1:

是否可以将服务(或 DAO)直接注入 UI 组件? 示例:在邮件应用中负责显示联系人的组件(ContactWidget,基于VerticalLayout with Links)需要显示联系人。直接将contactRepository注入这个UI元素可以吗?

问题 2:

对主应用程序的引用被传递给大量 UI 组件,因为许多 UI 组件需要访问一些全局数据或调用主应用程序类上的全局方法 示例:Popup 组件具有打开新窗口的按钮,它应该是应用程序中主窗口的子窗口。因此弹出组件必须引用主应用程序。

问题 3:

UI 组件之间的依赖关系可能会变得非常疯狂。这里可能没什么可做的,但有时感觉这个窗口并不依赖于这个依赖于弹出窗口的列表......你明白了,它看起来与我紧密耦合

在我的代码转为 Spaghetti 之前,我想尽可能多地了解 Vaadin 的优秀设计,因此我们将不胜感激任何建议、经验和最佳实践.

【问题讨论】:

【参考方案1】:

我们在使用 MVVM 模式(又名Fowler's PresentationModel)时非常幸运。他的文档有点旧,但起点不错。

看完之后,我的回答可能更有意义

    没有。将您的服务注入您的 ViewModel。 ViewModel 将是一个外观(并且可以封装适配器、装饰器、缓存和您决定需要的任何其他模式)

    我在这里没有看到任何问题,但我们确实遇到了与您所描述的情况类似的情况。我们使用 Guava 的 EventBus 在解耦的组件之间进行通信。这样,如果需要弹出新窗口,可以: eventBus.post(new NewWindowRequest(theComponent)) 并且你的主应用可以订阅同一个事件,然后弹出窗口。

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

我最近做了一个presentation on MVC vs MVP vs MVVM。示例代码可以帮助您理解从 MVC 到 MVVM 的转变。它是用 javascript 编写的,但它非常简单,我相信大多数人都可以遵循它。欢迎您提出任何反馈意见。

【讨论】:

感谢尘土飞扬。我最终选择了基于 Guava 的 eventBus 的手工 MVP(非常轻量级)和事件传播。我对这个决定感到非常满意,尽管令人惊讶的是 Vaadin 没有可靠的 MVP 框架(尽管有很多 betas/alphas/experimental)。 是的,好吧,尽管它已经存在了很长时间,但它并没有足够多的追随者来获得其他技术所获得的工程师爱。大多数使用它的人都在寻找最简单的解决方案,或者如果您像我们一样,没有足够的时间来记录我们正在做的事情。手工打造是一个非常不错的选择。概念是重要的部分,大多数 MVC/MVP/MVVM 框架只是为了确保你在线条上着色。如果你有纪律,它们通常不是必需的。【参考方案2】:

Vaadin 是一款很棒的软件,您绝对不应该使用意大利面条式代码。无论如何,一切都取决于你。

回答 1

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

Vaadin 定义了遵循著名的 MVC 模式的高级数据模型。共有三个嵌套层:容器、项目、属性(还定义了属性查看器和编辑器)。 Vaadin 的书提出了很好的类比:电子表格应用程序。所以容器、项目和属性将对应表、行和单元格。容易想象——容易理解。最后,ItemContainer 将揭示它的本质,您将理解这是任何良好且灵活的基于 Vaadin 架构的关键契约。我建议查看 Vaadin 的书,以获取所有其他详细信息:

https://vaadin.com/book/-/page/datamodel.html https://vaadin.com/book/-/page/datamodel.container.html

您还可以查看任何 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 易于使用,因此在更改主代码库之前,请随意做一些小型 PoC 和演示。

建议你也可以试试 MVVM https://vaadin.com/directory#addon/bambi-mvvm

【讨论】:

感谢您的回答,我检查了 bambi-mvvm - 看起来很不错,但它非常不完整,未经测试和测试。我发现的大多数与 MVVM/MVP Vaadin 相关的东西都是一样的 :( 不客气。 Vaadin 太年轻了,或者说比较年轻更好:) 就我个人而言,我更喜欢自己实现 Container, Container.Indexed, ... 来获得分页和其他一些功能。

以上是关于Vaadin:设计模式 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Vaadin Flow 应用程序自动在明暗模式之间切换

社交网络的 Vaadin 前端? [关闭]

Vaadin 和 Hibernate - 正确关闭与数据库的连接

我可以创建单例 vaadin 组合框组件吗?

Vaadin 中的休眠会话错误

Vaadin 14 '在重新打包后无法导航到“'