查看原文
其他

什么是好代码?

码农翻身 2018-10-25

“什么狗屁代码,老子看了几个小时也没明白!”


“这么烂的代码,到底是谁写的!”


Bob大叔说:“衡量代码质量的唯一标准是阅读该代码时说脏话的次数”, 真是很有趣的说法。



什么是好的代码? 这个问题可能是仁者见仁,智者见智。 我先说说我的看法,欢迎大家留言讨论。


我个人觉得好代码分为两个层面, 一个是道,一个术。


1好代码之“道”


“道”这里指的设计,是对问题本质的洞察,是良好的抽象。


对一个好的系统设计来说,我觉得有这么一个重要的特点: 系统由几个基本的概念组成,这几个概念体现了系统的本质,形成了系统的骨架,他们非常地稳定,生命周期很长。


系统的其他代码围绕着这几个基本概念生长,变化,扩展,不断地演进。


举个例子, Linus 把Git的数据结构设计得非常精良,据说在之后十年的开发中,feature 扩展了无数,基础数据结构却很少变动。


我相信Linus在开发第一版Git的时候,肯定对它要解决的问题--分布式源码配置管理--有着深刻的洞察,实际上Linux内核的开发就是一个典型的、分布式的架构和流程, Linus要做的就是创建一个匹配这个流程的工具,基于对问题的深刻理解,他设计出了Git的系统骨架。


正所谓“简约而不简单”。


但是“道”这个东西太虚无缥缈了,有没有一些可以真正指导我们做设计的准则?


在面向对象编程的领域,这个道就是面向对象的设计原则,Robert Mafrtin在《敏捷软件开发 原则、模式与实践》中总结了SOLID原则。 


Single responsibility principle : 单一职责原则

Open/closed principle :开闭原则

Liskov substitution principle :Liskov替换原则

Interface segregation principle :接口隔离原则

Dependency inversion principle : 依赖反转原则


如果我们设计出的类能满足这些原则,就不会有僵化、脆弱、重复、晦涩等种种可以导致代码腐化的问题。代码就容易扩展,生命力就会长久。 


但是这些核心的、优美的设计很有可能在进度的压力下出问题:做个简单粗暴的修改,就能省好几天功夫,不用晚上加班了, 很少人能经受这样的巨大诱惑。 所以要坚决守住这些核心的设计,防止腐化。


如果你做的是基础组件的开发,为别人提供服务和API,那必须在设计层面狠下功夫才行,因为API的每次变化都会极大地影响上层应用。


很多人使用Spring做业务软件开发,使用的无非就是Controller, Service, DAO这样已经划分好的结构,增删改查就搞定了,似乎感受不到设计带来的力量。 但我相信,系统中或多或少隐藏着几个核心的数据结构,你只是没有注意到而已。


如果业务很复杂,不要让他们分散在系统的各个地方,要对他们做抽象,形成一套可以独立的,不依赖框架的,生命力长久的业务模型。


2术:写代码的十八般武器


术就是编写代码时的具体技巧和最佳实践。 


这些技巧和实践在很多书中都有描述,比如《Effective Java》中提到的很多:

使可变性最小化

接口优于抽象类

优先考虑泛型

通过接口引用对象

遵守普遍接受的命名惯例

......

再比如《编写可读代码的艺术》和《代码简洁之道中》总结的技巧:

避免if嵌套的层次过深,形成“金字塔”代码

局部变量申明尽可能靠近使用的地方

如有可能,尽可能用常量

减少控制流变量

拆分超长表达式

函数应该短小,只做一件事情

把过多的参数封装成类

......


把这些“术”应用到编程当中,会让代码更加的专业。


很明显,这些技巧和实践比较容易学习,程序员学会了一门语言以后,应该去掌握它们,让自己的代码变得简洁可读。


相对于“术”,“悟道”就难得多,洞察问题本质,做出良好抽象,遵循设计原则,这都是内功,都需要不断修炼。 


但是这些“道”直接决定了系统的未来方向,设计得不好,再多的“术”也于事无补。


相关阅读:

烂代码传奇

(完)

你看到的只是冰山一角, 更多精彩文章,请移步《2016文章精华》或者《2017文章精华


码农翻身

用故事讲述技术

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存