为什么跟随视频写代码让人绝望

记得最开始学习Java和J2EE的时候,最大的困惑无疑是:我怎么知道应该这么去写代码?不这样可不可以?

培训中心善用的教材是:写一个坦克大战的GUI游戏,写一个blog或论坛,又或者写一个类似QQ的即时通讯工具。

而教学步骤一般都是:嗯,先要有一个界面,来,于是造一个canvas。再来,需要有坦克,我们就写一个坦克的class。再来需要有子弹,于是给出子弹。再来是子弹移动,于是给它坐标。

又或者是,要写一个聊天工具,先写一个客户端。嗯,因为需要连接,所以给一个socket。嗯,又因为需要接受,所以给一个socket的客户端。

艹!完全不知所云!我TM怎么知道这里需要有一个socket?!我连socket是啥都不知道。写一个坦克类或许是清楚的,但为什么要写坐标?为什么只是写了坐标就能发挥作用?为什么又要写子弹?

这样去学习,只会越学越乱,越来越不知道代码该怎么写。要写聊天工具,你连网络是什么、网络的原理、socket存在的意义都不知道,你说要写网络聊天工具?那还不是依葫芦画瓢,自己啥都不知道。

而你要写坦克游戏,首先,你根本就不会需求分析,更不懂软件工程中如何去解耦,将变化隔离开。根据需求分析,你首先需要判断清楚,在这样一个复杂的业务逻辑中(即坦克的移动、发出子弹、消灭其它坦克等),哪一些行为可以被归为一类,哪一些动作是可以附带在一个对象里的。

(更进一步,你可能还不大懂什么叫做前后端分离:哪一部分负责图形界面的构建,哪一部分负责数据的计算,通过什么方式将两部分衔接起来?什么样的东西才能作为衔接两端的桥梁?是否需要它是业务逻辑不变的?为什么需要前后端分离?为什么这样分离后、保持了业务逻辑不变后,就能够呈现最好的交互方式?

如果你没有办法回答这些问题,相信我,你根本没办法明白教学视频里怎么就嗖地一下凭空而出了一堆代码。而且你完全不知道,这些代码为什么会以各种割裂的方式进行组织。为什么要这么组织?为什么要这么分隔?我怎么知道应该这样分隔?这样分隔为什么就是对的?

写代码貌似是一个实现功能的简单事情,但其实不是的。如同数学,如果你不明白写代码背后的指导思想,不明白仅仅是基于“控制复杂度”这么一个基本出发点会有哪些技巧,会如何去运用“隔离变化”,那么,你就无法看懂、看明白表面上“割裂”的代码。而这些切割方式的理由和考虑,正是牢牢建立在对这些思想的深刻理解之上。)

这些决策并不是一拍脑袋就出来的,而是反复地尝试和推敲。有时候,最终的解决方案根本就有多种,哪一种合适取决于你面对的需求的限制。从草稿中,逐渐剥离出需求有哪几条,从梳理清楚的需求中去归纳出可能的组合,再从这个试探性的组合中去推演,看它们能否满足业务的所有流程和逻辑。

最后,当所有这些沙盘推演都结束了,才开始写代码。此时,你的大框架早已确定,只是在每一个已经想好的部分填充上细节。进而,在细节处去思考,有没有可以优化的空间,又或者是,写上一段代码后,你需要进行重构,看能否提取出一些公有部分的服务,让所有的变化集中在一处,以实现低耦合。

如此这些功夫,并不是能够简单地通过跟随视频写代码来解决,而是需要反复不断的思考、他人(可以是书本里的大师)的提点、以及已有代码的重构来磨炼。明白了核心的思想,那些割裂的、貌似无关的东西,才能够被有机地整合在一起。

同样的割裂和迷惑,还有计算机领域里很多的术语、繁琐的步骤、繁杂的参数。表面上,它们毫无章法,似乎就是凌乱的一堆东西。可实际上,当你的认识逐步加深,你会发现背后拿一根线。

例如,Java并发中的thread pool繁杂的7个参数,blockingQueue的各种API接口,Fork/Join, Future等数不胜数的框架,都会让你在第一眼看到时感到头昏脑涨。可是,一旦你明白了并发依托于队列的处理方式和原因,一旦明白了在构造队列时可能会出现的问题,那些繁杂的参数一下子就变得显而易见。

所以跟学习数学一样,当你发现你很难理解一个课题,很难掌握和消化一个问题繁复的参数或者状态时,你应该警醒:你还没有抓住本质。你需要更深入地挖掘背后的指导思想,直到这些纷繁的现象对你来讲变得不用去死记硬背,只不过是最基本的逻辑推理。

你可能感兴趣的:(java)