平凡却又深刻的编程理念:生命周期
生命周期(Life Cycle)是一个很简单的概念,但我觉得它经常被忽略或不够重视,尤其对于使用面向对象编程语言的程序员。
有时候我觉得调侃程序员没有对象是很正常的事,因为很多程序员不怎么理解生命周期的意义。他们很可能喜欢都使用静态类,认为对象一直存在;或者认为在需要的时候能够随意地创建(new)对象。没有对象的程序员该好好反思自己是不是也这样考虑生活中的对象。
而深刻理解生命周期重要性的程序员应该会知道,在生活里在合适的时候找到一个和自己生命周期一致的对象不是一件简单的事情,正如很好地设计和管理代码里各个对象的生命周期。
有些扯远了。回归主题。
生命周期就是一个对象的生老病死。
广义上的生命周期,即“从摇篮到坟墓”(Cradle-to-Grave)的整个过程。这个概念应用十分广泛。如果你平时涉猎各类社科领域的书籍,应该会不少看到。
对于程序员,我们接触的生命周期主要有哪些?
首先,应该是程序执行的生命周期。
注意这里说的是程序执行的生命周期,而不是程序的生命周期。然而,往简单来说——程序被触发,被加载,到被执行结束,没什么好说的。往细里说,这个输入是怎么触发的,代码是怎么加载的,执行的过程处理器、内存等怎么协同执行的,这个也不是这个专题想说的,所以也不细聊了。这里只要知道要理清一次程序执行或一次服务请求处理的生命周期,主要理解是如何触发的,如何判断它在执行的和正常结束即可。例如,在接触新的工程时,最好的熟悉的方式就是先理解其中程序时如何运行的,它支持的功能是什么,如何触发,什么是预期的结果,等。
其次,要理解代码执行的生命周期。
以面向对象编程为例,主要说的是对象的生命周期。在设计一个类的时候,我们要考虑清楚它的生命周期应该是如何管理的,比如怎么创建,活多久(全局单一实例,还是每次执行创建新的实例,等),需要如何销毁。
在实际工程里,所幸的是大多会有成熟的框架,其中应该会有依赖注入(Dependency Injection,DI)的容器管理所有对象的生命周期,比如ASP .NET Core有DI的支持,或者直接使用Unity Container等。这个时候,写业务逻辑的程序员不得不考虑给对象配置合适的生命周期,从而避免了许多低级的设计错误。
如果你不幸地工作在一个没有DI的工程里,希望你就可以把DI加进去。如果不可以,那你就只能认真地理解好每一个对象的生命周期了,直到工程的复杂度发展到无法控制的程度进而导致一次重构或重写,然后再记得考虑DI。
到了要负责项目或产品的时候,我们得去认识到项目或产品也是一种有生命周期的对象。这时候,我们对生命周期的关注不仅仅是创建和结束,还需要关键它的具体发展。我们需要清楚看到项目或产品当前的阶段(开发阶段,引入阶段,发展阶段,成熟阶段或衰退阶段),进而做出合理有效的计划和资源调配。其中,我觉得最重要是能识别衰退阶段并做好撤退计划,以及能够承担开发和引入阶段的风险。
在现实生活中,凡是需要长时间经营的事,比如爱好,我们都可以运用生命周期去看待。而且大多这样的事,生命周期都比较漫长,许多长时间投入才能有良好的发展;而生命周期的结束,很多时候是很被动的,而且很无助。
运用生命周期的概念去思考生活中的事情,收获的也许是一种更豁达的心态,因为我们接受了凡事都有起伏这种常态,然后达到“不以物喜,不以己悲”。