• 收藏

通过一个案例来看看代码的可扩展性

2017/9/15 9:03:10   易思捷科技


作为一个程序员,毫不夸张的讲,代码的可维护性及可扩展性是伴随着你的整个职业生涯的。

程序员,是无法控制需求的,而无法控制的这部分是极易发生变动的,这也是程序员最为苦逼的事情了。XP中最经典也是最无语的就是让我们拥抱变化。其实说的也对,面对变化,无论你是否乐意,你都得去拥抱,与其不乐意的拥抱,不如主动拥抱。所以,变化,成了软件开发唯一不变的内容。

也是变化,对我们的软件提出了严格的甚至为苛刻的要求,可维护及可扩展就成了非常重要的代码质量指标。

可维护及可扩展,从软件架构设计上就开始体现,分层,就是为了可维护及可扩展,现在成熟的架构已经很多了,SSH、Spring,.Net下MVC,还有MVP,MVVP等等,所以,如果从软件架构上来考虑,分层的问题不用再费力了,至少对很多项目而言,直接可以拿来使用即可。

重点谈谈代码结构的可维护及可扩展。先说可扩展吧,可维护更容易理解一些。

由一个例子开始,有点长,就以讲座报名为例:

老师发起(创建)了一个讲座,学生想参见听课,就得先报名。从需求驱动来看,需要定义一个学生类,然后学生有一个动作,报名,当然报名后还需缴费。

于是,就有了一个学生类,写了一个方法,报名。在这个方法中,实现了听课费用计算,缴费(此示例默认计算出费用即成功缴费)及学生与课程的关联,以实现报名操作,报名最重要的是两个环节,费用计算(免费及正常缴费)及学生与课程的关联。
没多久,老师又开辟了一些高端课程,譬如:项目管理,报名的人不是很多,所以,老师期望可以搞一些活动,最开始报名的10个人员给予6折优惠,以增加听课人数。

于是,苦逼的程序员就开始了第一次修改,在报名的方法中,需要添加这个优惠规则的处理,注意,程序员也不傻,把这个优惠的人数10和折扣6放到了数据库中,实现了可配置。这样就有了三个逻辑:免费、优惠、正常缴费。

培训开了几期之后,发现有些同学通过一次听课没有彻底学会,于是学校又出了一个政策,可以免费重学,以达到预期的学习目的。

程序员有点无奈,继续改,加一个判断的规则,如果以前报名,并且学完之后,再次报名,可以免学费重学。于是就又有了一个新规则。

又没多久,问题又来了,对于项目管理这类比较难的课程,重学率非常高,所以,需要控制每次开班重学学生的比例,均分到以后的课程开班期数中,以确保每次新生的比例。

程序员开始有点愤怒了,这种需求为何早不说?老师确实挺无辜的,谁能想到学了这么多次,还没学会呢?

改吧,控制一个比例,报名先判断是否重学,如果是再判断次数,然后自动均分到后续的开班期数中,这个时候,程序员发现,这个方法有点大了,有太多的if else了,并且每个都会有很多处理规则,于是程序员很聪明的把以前的一些规则都分离出来了,做成了一个私有方法,然后把一些可预料的变化规则,存储在数据库中做配置。结果就是报名就有了一个公开的方法:在此判断一些规则的调用,然后去调用一些私有方法。貌似现在还不错。

老师是终端使用者,所以老师又开始有疑问了,每次上课的时候,老师想知道重学的学生都是谁?可以在讲课的时候重点关注这些学生,帮助他们尽可能的掌握所学内容,重点培养对象么。

于是,程序员开始纠结了,学生类中也有这样的算法,让老师去创建一个学生类,调用这个方法?纠结,不应该吧,但就这样吧,私有改成公有,调用得了,项目重工期紧,先上线再说。再次的结果就是老师和学生类有关联了,而且很别扭的调用了一个方法。

可老师还是提出了意见,重复听课的计算方法有问题,因为有些学生虽然报名了,但由于各种情况,没有参加培训(请假了),因此第二次听课对于学生而言,还是属于初次听课。所以,要分离出这部分学生。

卧槽,这种情况难道不能提前预知么?老师很sorry,PM告诉你需要拥抱变化。再然后,程序员开始了艰难的工作,拆解代码,前面共用的重复报名算法不合适了。给老师拆分出一个方法来计算重复听课学生的请假情况,在老师类里面又多了一个计算方法,这样就出现了逻辑重复,同一个算法在不同的类中开始重复出现了。

还没改完呢,校长又说话了,重复听了两次课,还没学会,肯定是不认真,再听课,要加收一部分费用,但不能全收,按比例收取吧,给学生点压力,有压力就有动力么。嗯,两次不合适,三次吧,重复三次不能结业者,再报名,收取一定比例的费用。
程序员再次卧槽,PM再次告诉你要拥抱变化。

校长还没讲完,老师又说话了,如果有人介绍推荐来学习的,是否也可以给予一定的优惠呢?是否可以给推荐人一定的折扣呢?我们需要这样的模式,可以更好的招生啊。校长想想也对,OK!

程序员快疯了,照这样的改法,费用计算这块要乱了,学生要分两种情况,新报名和再次听课的,再次听课的还要区分是否超过了三次,每种情况,都需要按照自己的逻辑处理缴费。而且还要考虑推荐人的问题,还需要提出各种规则中的特殊情况。再同时,还得考虑重复报名的缺勤情况。

程序员真的疯了,不过疯归疯,改还得改,疯子也是可以写好代码的,终于经过艰苦奋战,改好了,老师表示很满意,校长也承诺不改了,PM也很高兴。程序员却很苦逼。

大家都表示很满意。课程也越开越多,老师很高兴,校长也乐开了花。闹事的人出来了,校长助理提出了一点建议,校长,学校运营状况良好,您看是否可以提供助学贷款,或者让学生分期缴费,以帮助那些想学习,但却无力承担费用的学生。校长一听,好啊,不错的点子,都涉足互联网金融了,搞。

一个“搞”字,结果直接把程序员搞掉了,程序员表示,这样搞法,几乎要推翻以前的工作了,结构要大变,不搞了,谁爱搞谁搞。PM苦劝程序员留任,未果,项目开始拖延了,好容易又招来一个程序员,看过代码后,当即表示,太乱了,无结构可言,真得推翻了重搞。PM很无奈,项目进一步延期。

新来的程序员表示,面向对象都很多年了,设计模式也应用很广,为何不去真正的面向对象,把关系解耦,便于扩展呢?听着很高深,来吧,看看结果。于是,下面的这张图就出现了,一个新的可扩展的结构出现了:


看上面这个图

1、所有操作都面向接口了;

2、在学生和讲座中都加入了付款策略,通过付款策略来调用相应的付款计算类;

3、付款费用计算通过策略模式实现;

这样,无论将来付款如何变化,只需要增加新的付款计算类就可以了,同时在学生或讲座中指定我们需要的这个付款策略,原有代码无需改动。甚至对于费用计算扩展而言,原有代码都可以全部封装,我们只实现新的费用计算规则,然后配置即可使用。
扩展就这样实现了。虽然可能我们初期的代码量会大一些,但为后期的扩展提供了基础。也许有些同学会问了,这个这个,谁也不一定会考虑到后期扩展的方向,那么在初期如何去构建这样的结构呢?

嗯,问的很有道理。所以,技术架构师很值钱。经验+能力。经验会告诉你需求变动的范围,能力,会告诉你解决的方案,另外一方面,能力也会让你发现需求的不稳定性,对于不稳定的地方要着重进行照顾。


版权声明:如无特别说明,均为“易思捷IT训练营”原创,如转载请著名出处!

阅读:236  评论:0  
  • 评论