友好的开发框架-Asta4D(6):副作用与Request Handler

1. Http请求的责任人-Request Handler

 

Asta4D虽然秉承View First的原则,但并不意味着在Asta4D中没有类似于MVC架构中Controller的存在,Request Handler可以看作是MVC架构中Controller的替代者。我们认为,对于每一个特定的Http请求,系统中理应存在一个角色对该请求承担责任,这个责任承担者,在Asta4D中,被称之为Request Handler。

 

基于View First的原则,在大多数时候,Request Handler是被省略的,或者可以理解为框架提供了一个缺省的Request Handler,它负责将请求导向对应的模板(实际实现上比这个要复杂一些,但概念上可以如此理解),那么,我们什么时候需要一个特定的Request Handler呢?

 

在回答这个问题之前,我们先讨论一下关于“副作用”的概念。

 

2. 系统操作的“副作用”

 

一个供用户使用的系统,必然提供诸多操作,简单的描述,可以说一个系统通常会提供查询操作,更新操作,等等等等。在这诸多操作中,我们需要意识到一个问题,就是不同的操作会给系统带来不同的影响,在Asta4D的思维方式中,我们认为,系统操作可以分为两个类型:具有“副作用”和不具有“副作用”。

 

一个具有“副作用”的操作,会显著的改变系统的状态,比如对于同一个url请求,在执行完一个login请求之后(如果成功的话),因为客户端权限的改变,很可能就会得到一个不同于login之前的页面应答。另一个更为显著的例子是数据库更新操作,一旦用户请求了一个更新操作,那么所有相关的客户端都会看到一个不同于更新前的数据—这就是所谓的“副作用”。

 

那么什么是没有“副作用”的操作呢?比如查询操作,无论你请求多少次同样的查询,你的请求都不会对系统状态造成改变,因此,一个查询操作是没有副作用的操作。有人会提到,如果我们对查询次数进行计数呢?我们仍然可以把计数操作和真正的查询操作分开成两个独立的操作,一个具有副作用,而另一个没有。

 

3. 隔离“副作用”与多线程渲染

 

我们认为,具有“副作用”的操作是需要慎重对待的,而Asta4D提供的解决方案,就是通过Request Handler封装并隔离所有具有副作用的操作。通过将所有的副作用隔离在Request Handler这一层,从而使得渲染层的逻辑变得更为简洁并富有弹性:既然所有的副作用都被隔离在Request Handler中,因此,我们可以非常轻松的实现多线程渲染--这是Asta4D极富特色的功能之一。

 

在传统的MVC架构中,Controller的职责是混乱的,既要承担改变系统状态的职责(数据更新),又要负责为View层准备数据,而为了解决延迟加载而经常不得不将数据库会话(事务)扩散到View层,使得事务管理也更加复杂。另一方面,特别是对于某些被分割为相对独立的区块的页面来说,虽然理论上可以通过多线程来为页面的不同区块同时准备数据从而提高响应速度,但这加大了代码的复杂度以及开发成本,在开发实践当中并不现实,因此,即使页面被分割为相对独立的区块,通常程序员也不得不顺序访问数据源为每个区块准备数据。

 

而对于Asta4D来说,通过在架构上分离副作用,从而使得系统的逻辑分层更为清晰。数据库会话(事务)扩散的问题不复存在,Request Handler的职责相当明确,只负责改变系统状态(数据更新)而不再负责为View层准备数据,而在渲染层逻辑中,数据的获取与渲染是同时完成的:我们在snippet方法中访问数据源,查询数据,同时立即在snippet方法中将数据传递给Renderer完成渲染逻辑。同时,因为对特定数据的访问被隔离在特定的snippet方法中,不再有跨层的调用和耦合,系统的复杂度也因此大为下降。

 

另一方面,我们只需要将不同的snippet方法的调用多线程化,就能够简单的实现多线程渲染,这一切对程序员都是透明的,而且因为所有的副作用已经被隔离在Request Handler层,即使我们对页面进行多线程渲染,也不需要考虑线程同步与互斥的问题--所有的view层的操作都是没有副作用的。

 

来看看我们如何简单的实现页面的多线程渲染:

 

<div afd:render="ParallelTest$TestRender:snippetInDiv" afd:parallel>
    <div id="test">xx</div>
</div>

<afd:snippet render="ParallelTest$TestRender:snippetReplaceDiv" parallel>
    <div id="test">xx</div>
</afd:snippet>

 

所有声明了parallel(afd:parallel)的snippet,都不会阻塞http request的主线程,http request的主线程会在完成所有的非parallel渲染后等待parallel渲染的结果返回,然后将合并的结果返回给客户端。

 

4. Request Handler与MVC的兼容性

 

有人大概会问一个问题:我们真的不需要MVC吗?真的不需要Controller吗?答案是No。我们承认,对于很多特定的用例来说,MVC的结构要比View First更为方便,特别是在处理Form提交的时候,很自然的就会要求MVC的架构。那么在Asta4D框架下,你只需要简单的将Request Handler当作Controller来实现就是了。

 

更进一步的,也许你无论如何都无法理解或者接受View First的理念,你认为Controller一定是必须的,但Asta4D分离的模板机制又让你动心的话,仍然是同样的回答:你只需要简单的将Request Handler当作Controller来实现就是了。

你可能感兴趣的:(java,Web,框架,asta4d)