案例二:定期自动更新宝宝年龄
1.模块概述
本模块功能如下:
1.宝宝年龄更新;比如宝宝8月份注册时1岁,生日8月8号,那么2018-8-8更新为2岁;
2.模块设计
2.1.功能模块
2.1.1.定期更新宝宝年龄
宝宝信息表baby_info:
宝宝id | 名称name | 年龄age | 生日birthday
1 | lucy | 1 | 2016-8-8 (注:当前日期是2017-8-12)
方案一:
服务器端启动定时任务:
1)每天定时扫描baby_info表;
2)读取birthday字段,与当前日期比较;
3)如果当天(2018-8-8)是宝宝生日,则更新baby_info,age+1=2岁
点评:
此方案逻辑正确,实现简单,可以实现宝宝年龄每年正确更新。
评审意见:
1. 新手很容易想到这样的思路,一般就直接开始写代码实现了,并一边实现,一边去考虑实现难点了。比如:定时任务库,生日判断方法等,直接钻进实现去了。
2. 功能实现了,测试没有bug,这个任务就完成收工,也再也不会想起优化了。
3. 直到某一天数据库中宝宝数量突破万级,定时任务执行效率极低,这时想到需要优化性能;
4.优化性能时又想到方案了,分布式:多几台服务器,多几个定时任务,每个任务扫描2000个宝宝信息;好了思路OK了,开始代码实现,性能测试又OK,任务收工,满足的泡一杯咖啡。这是大部分程序员的缩影!
再点评:
感觉没有什么不对哦。
难道是:方案一设计时就考虑多任务多线程等;不必等后面性能问题暴露了再改;
其实不然,而是再收到任务需求时,就应该停下来好好思考下,莫急于编代码!
多一点思考和分析,好一点的方案才是好程序的根基。
功能分析:
1.宝宝信息表baby_info中的宝宝数量只会越来越多,逐条扫描必定会效率低下,很快会遇到性能瓶颈;
2.宝宝生日是2016-8-8,则1岁是2017-8-8,下一年是2018-8-8;也就是2017-8-8更新年龄1岁后,下一次生日就是2018-8-8;
lucy 2016-8-8 1岁2017-8-8 2岁2018-8-8
jane 2016-8-10 1岁2017-8-10 2岁2018-8-10
3.上面的分析有发现什么特点没有?
1)不同生日的宝宝,更新年龄不在同一天;也就是分布在365/366天里面;
2)每次生日更新都是下一年。
有没有触发你什么灵感?
评审改进:
方案二:
1.改进宝宝信息表baby_info:
宝宝id | 名称name | 年龄age | 生日birthday | 下一次生日next_birthday
1 | lucy | 1 | 2016-8-8 | 2018-8-8
2 | jane | 1 | 2016-8-10 | 2018-8-10
2.宝宝注册时,初始化下一次生日日期;
3.启动定时任务:
1)每天定时从baby_info表中筛选去next_birthday等于当天的记录;
2)这些宝宝当天为生日,更新年龄age+1;
3)并计算出下一次生日日期,更新next_birthday;
点评:
新方案优势:
宝宝生日的更新分散到365/366天里面去了;定时任务执行只会扫描当天生日的宝宝,非当天生日的宝宝都过滤掉了,这样扫描的记录就少了很多。
至此评审结束。
结束语:
程序设计是一场逻辑思维的旅程,在code之前,停下脚步,好好思考,好好想想多个方案,写出来。
更好的程序,来源于更好的设计。
网友评论