现在设计模式很流行,但我觉得什么模式并不是重点,重点是对代码的语感,也就是我说的基础技巧。模式是需要经验,而不能囫囵吞枣,简单模仿。
很多时候,你不需要什么模式,只需要坚持一些“美感”就足够。
闲话少说,代码设计的几个基础技巧如下:
一、防止重复
不要重复自己,也不要重复代码。当你发现重复的时候,就想想用一个标识符去取代具体的内容。如果是常量,就用常量标识符,如果是变量,就用变量标识符,如果是代码段落,就用函数包装,如果是数据单元的集合,就建立相关的数据结构封装,如果是状态和调用的集合,就建立对象;如果要新的数据类型,就用struct定义。
只有不重复自己,不重复代码才能减少重复劳动,提高编码效率(体现在修改,和再次利用上)。
二、提高代码适用范围
基于上一步,得到的代码质量有高低之分。因此要对这些代码进行优化,务求得到更高适用性的代码。比如函数就根据不同的参数定义,有不同的适用范围。一个函数是高适用范围的,主要体现在函数功能是否单一,满足多个功能要求的函数,很少会被客户需要所有的功能,那么就等于可复用性更低;然后是功能是否以来外部调用和外部状态,如果以来外部状态,那么这个函数就需要当前的上下文环境,就要求客户端提供类似的上下文环境,这就能与对客户端要求更高,等于可复用性更低;然后是功能是否会改变外部状态,是否有副作用,副作用越多,那么客户端需要考虑的东西就越多,同样等于提高对客户端的要求,等于可复用性的下降。
只有适用范围广的代码,才能减少重复编写稍微不同的代码,等于珍惜了生命。编写高适用性的代码,主要是做减法,或者对参数的范围要有所放宽(比如使用更抽象的数据,而不是具体的数据),但是这里应该明白所谓适用范围只是度的把握,不需要编写万能的代码,这会对编码的能力有很高的要求,并增加不必要的复杂性。
三、减少调用的复杂性,而不是自身的复杂性
一段代码被复用,同时也会对客户端提出要求,一个好的代码,应该是对客户端友好的,在权衡取舍中,应该偏向优化调用的复杂性,而不是自身的复杂性。尽量把调用方的麻烦转嫁到自身内部,就算会增加自身的麻烦。
四、简化代码的结构性
意大利面式的平板代码,被很多人指责,但是好处就是结构单一,易于分析。而现在越来越多程序不断增加代码的结构层次,似乎认为架构越复杂,越灵活,就是越优秀的程序。包括这种模式那种模式的疯狂运用,本质上也是带来复杂的程序结构。但是我个人觉得这种结构复杂的代码极其难以分析。如非必要,应该减少结构性的代码,尽量以一个平面化,易于理解和分析的方式去组织代码。
五、先用自然语言编程
自然语言和程序设计语言有差别,但是大部分情况下,自然语言都能够很好的翻译成程序语言,而自然语言比程序语言优秀的地方在于,自然语言是我们脑海思考所用的语言,因此,使用自然语言编程能够最大化的表达自己,同时也帮助自己整理好逻辑思绪。很多人编程一开始就用程序设计语言,没有一个完整的思路,见步行步,出现较大的迂回情况。一般情况,先用画图,举例子等的模式找准思路,然后用自然语言表述一次,最后用程序设计语言实现,最后修正代码的错误。
六、先难后易
程序开发最怕的事情是修改,因此,要把难题先解决,而不是先把简单的事情做好,然后再推翻这些简单的事情。也就是说越早碰壁好处越大。对于程序来说,难点可能就是一两个算法的实现问题,因此写程序应该首先着重精力去解决这些底层的算法,然后再想实现业务逻辑等一般编程问题,然后才是高层的组织问题。从某种程度上,这是一种自底向上的设计思路。但是这种思路并不是一次性的,而是应该反复从下到上,从上到下的过程,设计不应该是一次性的事情,认识需要一个过程,设计也是如此。用两种角度去思考问题,程序首先要保证系统自身的特点,符合效率的原则,从而杜绝从高往低的不切实际的想法;再次从高往低着眼,才不会因为从低往高而让系统太特殊化,太具体化,而缺少抽象,缺少适用性的弊病。
一般来说,先实现核心算法,然后建立基础原型,最后根据原型进行高层重组,再根据设计稿从新实现和丰富原型,达到最终效果。喜欢折腾的人就不妨反复多次这个过程。