人有生老病死,一年有春夏秋冬四季演替,封建王朝有兴盛、停滞、衰亡的周期律——“其兴也勃焉,其亡也忽焉”。换句话说,人,季节,王朝等等这些世间万物都有自己的生命周期。同样地,在软件行业,一个系统,一个组件,一个功能,一个类都是有自己的生命周期的。
那么,为什么要从生命周期的这个角度去理解程序?
在现实世界中如果你使用一个工具,当你理解工具的工作原理的时候你使用起来无疑更加有信心、更加得心应手;应用的开发与此如出一辙,当你理解框架的运行机制时,你开发起来就会如行云流水,写起代码汪洋恣肆一发不可收拾。
每个程序的运行,要理解为一个过程或者流程。复杂的东西理解起来困难,我们分成若干个阶段来理解岂不是就简单许多了吗?除了我们更好的去理解程序的运行流程,更为重要的是还能够使我们能够“介入”这个流程,改变这个流程,从而实现我们的目的。
我们平时经常用的操作,比如ActiveRecord的insert操作,仿佛就是一步到位完成了。但其实我们深入到框架内部就会发现,其实看似插入数据这么一个简单的操作,还是分为几步完成的。beforeValidate->afterValidate->beforeSave->afterSave等阶段,从beforeXxx和afterXxx也可以看出一点端倪。到最后,其实是执行的SQL的insert语句,前面的无非是做了些面向对象的封装而已。那么,这些操作加之insert语句的执行,对于Yii2来讲已经是“原子操作”,不能再分割了。这些操作,构成了insert操作的生命周期。当然,生命周期也是有层次之分的,对于Yii2来说SQL insert语句是原子操作不可分割,但是对于MySQL本来来说,intert操作又可以分为几个阶段,也有其生命周期。因此,生命周期是相对的,抽象层次不同,生命周期也是不一样的。
另一个常见的例子是,应用本身(Application),Yii2官网有说明,我们不在赘述,任何想要学习Yii2的小伙伴都绕不开这个。我们这里仅仅介绍一下另一个有代表性的类——用户认证类User。看看它的生命周期是怎么样的。
User用来管理用户的登录/登出,在其中定义了四个基本事件:
顾名思义,就是登录前,登录后,登出前,登出后。这是四个事件,这些连同登录/登出动作本身,构成了用户登录行为的完整周期。
按照Yii2一贯的优良作风。这个登录/登出认证操作完全可以视作一个完整的过程,在这个过程的重要节点上标注事件,再事件上添加事件处理器。从而完成对整个过程的控制——是否继续执行,添加额外的动作等等。你可以通过响应这些事件来实现一些类似登录统计、在线人数统计的功能。例如, 在登录后 yii\web\User::EVENT_AFTER_LOGIN 的事件处理器,你可以将用户的登录时间和IP记录到 user 表中,也可以在EVENT_AFTER_LOGIN和EVENT_AFTER_LOGINOUT的事件处理器来记录在线人数。
因此,了解每个重要功能的生命周期,其实就是掌握其内在运行的机制,从而不再视其为“原子操作”,从而使我们能介入它、改变它,使之更好的为我们服务。