2017年3月

Flux和Redux基本思路

Flux和Redux的基本思路都是单向数据流,但是说单项数据流太抽象了,还是说得简单易懂:
本来在Flux提出之前,大家在DOM里面直接写业务逻辑,方便快捷。
但是问题也有,比如Facebook的团队发现的诡异的小红点的问题。
那么如何解决,那就是DOM中进行操作之后触发一个请求,这个请求再被分发器dispatch到业务逻辑。

那么这样有什么好处呢?
这样系统中的所有可用的请求都做成清单,一目了然。
所有触发的请求都会经过一次Dispatcher,简洁明了。
只有Dispatcher才能接触业务逻辑,这也就是单向数据流这个词的来源。

一句话,DOM不能直接改Model了,需要触发一个请求,Dispatcher接受到请求再执行业务逻辑。

React的路由模块设计

如果从React的角度设计路由的话,其实还是比较简单的。
比如如果点击一个链接触发一个新的路由,那么你可以在这个链接写上这样的触发事件:

在Flux中添加Action:

updateURL(new_url) {
    Dispatcher.dispatch({ type: 'UPDATE_URL', url});
}

添加一个存储URL的Store

getInitialState() {
    return '/';
}

reduce(state, action) {
    switch(action.type) {
        case 'UPDATE_URL':
            return action.url;
    }
}

在Flux Container引入事件:

onUpdateUrl: TodoActions.updateURL,

在View视图中触发事件:

<a onClick={props.onUpdateUrl('/myURL')} />

在顶部Component之上添加路由Component:

function Router(props) {
    if(props.url == '/') {
        return (<App1 {...props} />);
    }
    if(props.url == '/myURL') {
        return (<App2 {...props} />);
    }
    return (<NotFound {...props} />);
}

当然,这样是最简单的方案,但是实际中肯定不会用触发点击事件的方式去实现更改URL,而是直接给<a>标签一个href,然后用户点击href,被事件系统拦截到了然后自动被分配一个Action,然后被dispatcher进行dispatch。

还有,用户直接复制url访问的问题,此时就需要系统在系统启动时检查一下当前的url是多少,然后在getInitial中获取当前url。

另外,还有一个古老的问题,就是把访问历史要记得添加到history里面去。

最后,还有一点疑问,就是用户手动修改url可以被拦截到么?是不是就可以避免重新加载。

粗浅了解了一下Velocity模板引擎的原理

今天阅读了一篇文章,关于Velocity模板引擎原理的,很有收获,所以简单的概括一下。

其实,一直在思考Velocity这种模板引擎和JSP的区别,今天才恍然大悟。
其实Velocity可以称得上是半个语言了,所有的Velocity模板都会被分解成语法抽象树(AST)。如果对语法抽象树没有概念的话,可以了解一下《自制编程语言》一书(其实我也没有看过这本书)。
但是如何将Java的Context和Velocity最后分解出的语法抽象树匹配起来,这个才是问题所在。

这边可以对照一下JSP,JSP作为纯正的Java,自然不用担心变量的匹配的问题,所有通过Request的Attributes转发到JSP的对象都可以恢复原来格式的对象来调用。
但是Velocity中分解出的语法抽象树却需要通过反射等功能来获取Java变量的值,替换语法抽象树中的节点。

Servelt如何判断用户首次访问站点是否需要进行URL重写?

看到《Head First Servlet&JSP》的URL重写的时候,对这边就有疑问了。

Servlet如何判断客户端不支持Cookie而进行URL重写呢?毕竟用户的第一次访问站点都是不可能带Cookie的,那么如何判断这个是用户首次访问站点还是因为用户的浏览器不支持Cookie?

然后,找到了一篇文章:http://dk05408.iteye.com/blog/2103257,发现这个问题Servlet处理的太简单了。简单的来说,就是不处理,所有的用户第一次访问站点的情况都当成不支持Cookie处理,进行URL重写。等到下次访问的时候,就能正确判断支持不支持Cookie了。

这样的话,那么Servlet就会对每一个不支持Cookie的请求都会尝试设置Cookie,这也是一种没办法的办法。

SlimPHP框架运行原理

SlimPHP主要有两个大的部分,路由(Router)部分和中间件(Middleware)部分。
首先,我们需要了解的是路由部分。
其实路由部分没什么难度,Route对象主要存储的是来自map()方法的内容。
Router是一个控制器,所有对Route的操作都要经手Router,职责有创建Route对象和dispatch(Request)到匹配的Route。
匹配的Route将会被放到Request里面,Route中的Closure(其中有业务逻辑代码)在中间件部分执行。

然后,我们来了解一下中间件部分。
所有中间件会形成一个栈(stack)结构,从最外层的中间件到最里层的中间件依次执行。
当然,最里层的中间件会继续调用$next,那么这个$next是何方神圣呢?
其实这个$next就是App对象,在PHP中,有一个魔术方法__invoke()可以把一个对象当成函数来用。
这边的App类就有一个__invoke()方法,当调用到最里层的中间件的时候,就相当于会调用$app($request, $response)。
在这个__invoke()方法里面,将会调用路由部分存储在Request中的Route中携带的Closure业务逻辑。
具体怎么执行的,请查看相关代码。

差不多就这些内容。