首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这会是一个好的web应用程序架构吗?

这会是一个好的web应用程序架构吗?
EN

Software Engineering用户
提问于 2011-11-11 12:17:58
回答 1查看 1.1K关注 0票数 6

我的问题

我们基于MVC的框架不允许我们只缓存部分输出。理想情况下,我们希望缓存所有静态和半静态部分,并运行动态部分。此外,我们还需要考虑对数据库更改作出反应的数据缓存。

我的想法

我提出的概念是将页面表示为XML片段对象树。有些片段是动态的,可以直接从模型或其他来源提取它们的数据,但是大部分碎片是静态的脚手架。

如果片段子树是完全静态的,那么我设想它们可以展开成XML,然后缓存为父元素的文本表示形式。

理想情况下,这个过程将继续进行,直到我们得到一个包含所有静态XML的根元素,并在页面显示之前解析并附加到XML树的相关节点上的动态XML片段。

除了将内容分离为动态片段和静态片段之外,一些片段还可以是动态的和缓存的。通过XML片段树传播的简单的过期时间将指示应该定期刷新特定的片段。报纸部分或头版不需要每秒钟更新一次。几分钟甚至更长的时间就足够了。

其他碎片将是动态的和未被发现的。通常,要缓存的文章太多了--缓存会溢出。如果个别的文章非常受欢迎,它们可能会被缓存。

函数符

折叠机制可以是足够聪明的,可以判断何时折叠动态缓存片段并将过期日期传播到父片段,或者在解析页面时将其保持分离并简单地附加到XML树。

如果某些动态缓存片段通过全局唯一内容id之类的机制与数据库对象相关联,那么对数据库的更改可能会触发对输出缓存的更改。如果片段存储父片段的标识符,那么它们可以触发重新折叠过程,然后包含更新的数据。

一组纯XML具有有序的片段对象数组(每个数组存储它们应该附加到的节点的标识信息),可以通过遍历XML树和合并片段中的数据以相当简单的方式解析。

因为在附加节点之前不需要在内存中解析和构造整个树,所以处理应该相当快。

每个片段的标识符将是相关身份数据和碎片对象类型的组合。缓存的父片段将包含对这些标识符的引用,以便从片段缓存中提取它们,或者运行它们的代码。

控制器的责任被简化为对数据库进行更改,并告诉根XML片段对象呈现自身。

我只想说清楚,当我说XML时,我真正的意思是XHTML。该设计从一开始就生成和折叠XHTML,而不尝试添加将XML转换为XHTML的额外步骤。它在功能上等同于XML。

更新:

设计基本上仍然是MVC。传统上,在Web应用程序中,控制器直接对模型进行更改,然后加载来自模型的所有数据,并将其发送到视图。

这方面的问题是很难进行部分页面缓存。

大多数web应用程序大部分时间都花在DB上。如果控制器每次都必须从模型加载数据,那么缓存视图就没有意义了,除非您缓存整个视图并且不执行数据库查询。

然而,在MVC模式最初来源的Smalltalk中,视图直接从模型中提取数据。“视图从模型中获取自己的数据。”- 维基百科上的MVC

如果视图从模型中提取数据,而视图是由其他视图组成的,那么缓存视图的输出就变得非常简单。如果它不需要再次加载,那么它就不会加载,也不会与DB联系。

我将视图输出作为XML/XHTML来处理,因为我们有几个工具可以很好地操作XML,使得静态和动态片段的交织相当简单。

问题

我的问题有两部分:

  1. 这是个好设计吗?我有什么明显的缺点吗?
  2. 以前有人想过这个吗?推荐人?
  3. 我是否应该考虑现有的替代方案?也许是个很酷的模板引擎?
EN

回答 1

Software Engineering用户

回答已采纳

发布于 2011-11-16 12:00:12

这听起来像是在试图发明输出缓存。我肯定不同意在MVC中很难进行部分页面缓存,只是您需要使用部分视图和它们自己的Controller操作来实现,而不是让视图本身调用它的子视图,这可能有点违背直觉。(因此,在ASP.net MVC中,您可能希望使用Html.RenderAction而不是Html.RenderPartial)。这个特殊模式的名字目前正在逃避我的记忆。

我建议你的设计的主要缺陷是视图必须了解网站的架构。因此,他们必须知道从哪里获取数据,以及如何获取数据,他们必须知道在哪里缓存数据,什么时候缓存数据,什么时候不缓存数据等等。

实际上,您应该尝试将层与其他层的知识分离开来,因为每个层拥有的知识越少,更改层就越容易(即切换DB、添加透明的数据缓存层、将DB调用移动到web服务,等等)。

我建议,如果您要实现这样的想法,并且在您的MVC框架中没有本地的输出缓存系统可供选择,那么您应该将缓存层添加到Controller操作中。除非您有一些非常重要的视图需要对模型进行大量递归呈现(这是非常罕见的),与DB调用和客户端网络延迟相比,实际的HTML生成时间很小,所以采取一种更实用的方法,在需要缓存的地方缓存,即在应用层。

如果您确实需要自定义输出缓存,那么您可能只想在Controller操作之上插入缓存层,使用包装类(如果使用动态语言)或接口的不同实现(如果使用静态语言),可以劫持对Action的调用并作出相应的反应。

至于对DB更改作出反应的缓存,您最好使用一个缓存层,它考虑到存储库类中的加载和保存,每个保存调用刷新缓存(或缓存集的一部分),每个负载在需要时从缓存降为DB (即,当缓存数据可用时使用缓存)。这样,您就可以将数据库驱动的行为保持在接近数据库的位置。

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

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

复制
相关文章

相似问题

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