首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >什么是“分离数据模型”,在"Java并发性在实践中“一书中提到的?

什么是“分离数据模型”,在"Java并发性在实践中“一书中提到的?
EN

Software Engineering用户
提问于 2016-01-14 12:25:19
回答 3查看 836关注 0票数 4

我正在通过"Java并发性实践“一书学习Java多线程编程。在第9.4.2章中,我看到了以下内容:

从GUI的角度来看,Swing表模型类(如TableModeltreeModel )是要显示的数据的正式存储库。然而,这些模型对象本身往往是应用程序管理的其他对象的“视图”。具有表示域和应用程序域数据模型的程序被称为具有拆分模型设计(福勒,2005年年)。在拆分模型设计中,表示模型仅限于事件线程,而另一个模型共享模型是线程安全的,可以由事件线程和应用程序线程访问。表示模型向共享模型注册侦听器,以便在更新时通知它。然后,可以通过在更新消息中嵌入相关状态的快照,或者让表示模型在接收更新事件时直接从共享模型检索数据,从而从共享模型中更新表示模型。快照方法很简单,但也有局限性。当数据模型较小,更新不太频繁,且两种模型的结构相似的情况下,它工作得很好。如果数据模型很大,或者更新非常频繁,或者如果拆分的一方或双方包含另一方不可见的信息,则发送增量更新而不是整个快照可能更有效。这种方法的效果是序列化共享模型上的更新,并根据表示模型在事件线程中重新创建更新。增量更新的另一个优点是,更细粒度的更改信息可以提高显示的感知质量,如果只有一辆车移动,我们就不需要重新绘制整个显示器,只需要重新绘制受影响的区域。

“分离数据模型”的含义是什么?你能给我举个例子来帮助我理解它吗?

EN

回答 3

Software Engineering用户

发布于 2016-01-14 16:11:01

表示域数据模型涉及到在屏幕上呈现应用程序域数据模型。例如,假设您在应用程序数据模型中有一个表,并希望根据用户的选择显示筛选和/或排序的数据。在这种情况下,筛选器和/或排序的选择是表示域的一个方面。(过滤器/排序可以表示为数据,甚至如果用户希望检索相同的视图,也可以持久化。)

通过将表示模型的关注点从应用程序模型中分离出来,我们可以很容易地创建一个应用程序,该应用程序可以同时对同一应用程序数据进行多个视图(演示)。假设一个用户打开了多个窗口查看相同的应用程序数据,尽管显示方式可能有所不同(在我们的示例中,可能排序或筛选不同)。

现在,也可以想象两个或多个用户查看相同的数据(可能使用不同的过滤器/排序)。一旦有多个用户可能(通过他们各自的演示)更改相同的数据,我们就需要在应用程序模型上应用多线程协调(事务、锁或其他)。

相反,表示模型不需要线程协调(除非您持久化视图并允许多个用户编辑它们)。

票数 1
EN

Software Engineering用户

发布于 2016-01-14 12:48:28

这里的想法是使用事件增量地更改事物,而不是每次用户需要“最新数据”时刷新模型。

例如,假设一个应用程序显示数据库表的内容,例如,在一个复选框中。通常,当您刷新组件时,应用程序会查询整个数据库表并更新整个列表,即使90%的列表中有相同的元素。

现在假设第二种情况。你有一张不同部件的报警器表。与其定期轮询它们,不如等待它们中的每一个在发生事情时通知您。所以你实际上是在倾听事件,而不是每次都问“好吗?可以吗?”

OSGI就是一个例子。例如,Eclipse使用OSGI (春分)来管理其模块和插件(实际上,Eclipse本身就是一个大型插件管理器)。更新模块或安装新插件时,不必重新启动整个应用程序来加载更改。相反,Eclipse由OSGI引擎通知,并通过事件重新加载更新的部分。因此,更改是逐步更新的,在大多数情况下,不需要重新启动应用程序。

票数 0
EN

Software Engineering用户

发布于 2016-01-15 00:05:13

考虑一下控制复杂仪器的软件。它周期性地轮询仪器以读取一系列值:电压、压力、完成百分比、警告标志等。想象一下,数据在USB或以太网上以XML/JSON或二进制形式出现。该数据将显示在非模态对话框中,供用户监视。该对话框可能是双向交互,即有一个“中止”按钮。在Java中,可能会有一个线程执行这个轮询,然后解析数据。许多其他语言也会有类似的效果。

那么,把数据放哪里,怎么放呢?

在该对话框的深处,面板中有一个面板,其中包含一个滑块、按钮或TextField来显示这些结果。这些深埋的数据是否有理由成为该文书官方真实状态的模型、官方真实储存库?例如,如果电压太高,您想要弹出警报或发送电子邮件,那么该代码是否需要通过嵌套的JPanels查看?不是的。

您的轮询线程知道如何在该对话框中找到按钮是合理的吗?如果它知道要做什么(对坏代码挥手) getComponent(EAST).getComponent(3).getStatusTextField().setText("4.56 pounds");几乎肯定不会。如果你遵循德米特定律,这可能会变得更简单,getEscapeModuleForCapsule3StatusTextField()。但即便如此,也会在线程和GUI之间创建大量的链接。如果您还想拥有一个Android版本和一个HTML5版本的代码呢?如果市场部将一些小部件更改为滑车或旋转器,该怎么办?用公斤的欧洲版怎么样?如果在三个不同的JPanels上,电压场实际上是3个相似的场,两个是文本,一个是旋转器,那该怎么办?

好吧,我承认我有点夸大了前两个问题。

最重要的是,这是本主题出现在JCiP中的主要原因,即使您解决了所有这些问题和设计问题,以便轮询线程能够到达相关的小部件,修改值也很麻烦,因为Swing是单线程的。来自轮询线程的所有调用都在错误的线程上,必须用尴尬的SwingUtilities.invokeLater(new Runnable() { public void run() {// real code here } });包装

共享数据模型

在“共享数据模型”中,您可以自由地以更自然的方式进行操作。您定义了一个InstrumentModel类,一个对您的公司和工具有意义的类,包括相关的设置器、获取器,以及,哦,是的,边界检查。当电压太高时,它可能会引发特殊事件。对于您的内部科学家和工程师来说,这个模型比许多嵌套的JPanels更有意义。这个模型必须是线程安全的。

请注意,这个模型不知道它是否将是Swing,GWT,HTML5或美国手语的输出。这就是脱钩。轮询线程将数据放入InstruementModel。然后它(或其他什么)向GUI激发一个事件--以最简单的形式,theHugeDialog.repaint();注意到,在Swing中,这些重绘请求是排队的,因此,希望您的对话框不会在每次更改中重新绘制1000次。

paintComponent()或类似的图形用户界面中(有一些问题),然后从InstrumentModel中提取数据。它是在正确的Swing AWT线程上自动运行的,因此不需要invokeLaters()。由于您巧妙地使InstrumentModel线程安全,所以读取数据与PollingThread写入数据并不冲突。如果主应用程序窗口中也有VeryImportantVoltage文本字段,那么它也可以从InstrumentModel更新。

这是“快照”更新-基本上,您重新绘制整个GUI。如果GUI很大,并且每秒更新100次,这可能太慢了。然后进行增量更新,其中只更新更改过的数据。这件事很快就变得复杂起来。

票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/307389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档