到处都在谈论 UI 的美感,仿佛 “美” 在软件工程中的定义就要落到界面上面。实际美的存在是广义的,包括架构设计,包括代码建设,包括接口定义,不妨在更多的场合引入对美的评审。软件本身就是一种艺术品,而程序员,应当是被赋予创造力的艺术工作者。
仅看这两张图,你觉得哪一张会更美一些?
我相信大多数人会选择第一张,因为后面那张图显得头重脚轻,事实上,后者也确实是一个短命的版本,只存活了不到半年的时间。这两张图,正出自淘宝发展的一个阶段(来自淘宝赵超的博客)。而且,进一步观察发现,对于许多设计图来说,狭窄的汇聚点往往成为性能的瓶颈。
另一个设计上典型的丑陋是混乱,如下面的设计图:
我不相信看到了这样的关系图的人会觉得这是一个好的设计。有人说 “简单就是美”,兴许有人不同意,但是太过复杂一定是丑陋的。
代码层面的美亦然。先来看这样一段代码:
#i nclude <stdio.h> main(t,_,a)char *a;{return!0<t?t<3?main(-79,-13,a+main(-87,1-_, main(-86,0,a+1)+a)):1,t<_?main(t+1,_,a):3,main(-94,-27+t,a)&&t==2?_<13? main(2,_+1,"%s %d %d\n"):9:16:t<0?t<-72?main(_,t, "@n'+,#'/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l+,/n{n+,/+#n+,/#\ ;#q#n+,/+k#;*+,/'r :'d*'3,}{w+K w'K:'+}e#';dq#'l \ q#'+d'K#!/+k#;q#'r}eKK#}w'r}eKK{nl]'/#;#q#n'){)#}w'){){nl]'/+#n';d}rw' i;# \ ){nl]!/n{n#'; r{#w'r nc{nl]'/#{l,+'K {rw' iK{;[{nl]'/w#q#n'wk nw' \ iwk{KK{nl]!/w{%'l##w#' i; :{nl]'/*{q#'ld;r'}{nlwb!/*de}'c \ ;;{nl'-{}rw]'/+,}##'*}#nc,',#nw]'/+kd'+e}+;#'rdq#w! nr'/ ') }+}{rl#'{n' ')# \ }'+}##(!!/") :t<-50?_==*a?putchar(31[a]):main(-65,_,a+1):main((*a=='/')+t,_,a+1) :0<t?main(2,2,"%s"):*a=='/'||main(0,main(-61,*a, "!ek;dc i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m.vpbks,fxntdCeghiry"),a+1);}
我不相信你能一下看懂。但是它给你的第一感觉是什么?“极其混乱”,对不对?混乱而且无比丑陋。事实上,它正是国际混乱 C 语言大赛 1988 年的获奖作品。
再来看看 OSCache 中的一段代码:
if (this.isStale(cacheEntry, refreshPeriod, cronExpiry)) { EntryUpdateState updateState = getUpdateState(key); try { synchronized (updateState) { if (updateState.isAwaitingUpdate() || updateState.isCancelled()) { updateState.startUpdate(); if (cacheEntry.isNew()) { accessEventType = CacheMapAccessEventType.MISS; } else { accessEventType = CacheMapAccessEventType.STALE_HIT; } } else if (updateState.isUpdating()) { if (cacheEntry.isNew() || blocking) { do { try { updateState.wait(); } catch (InterruptedException e) { } } while (updateState.isUpdating()); if (updateState.isCancelled()) { updateState.startUpdate(); if (cacheEntry.isNew()) { accessEventType = CacheMapAccessEventType.MISS; } else { accessEventType = CacheMapAccessEventType.STALE_HIT; } } else if (updateState.isComplete()) { reload = true; } else { log.error("Invalid update state for cache entry " + key); } } } else { reload = true; } } } finally { releaseUpdateState(updateState, key); } }
这样的代码片段虽然没有那么混乱,但是远谈不上美,看起来还是很辛苦,其中复杂的状态变量依然让人觉得很难理解。这段代码片段正是来自 OSCache 的 Cache.java,也是 OSCache 中 bug 很多,也遭人非议最多的 NRE(NeedsRefreshException)机制中的核心代码,事实上,代码的 contributor 们已经意识到其中的坏味道了。
有意思的是,OSCache 代码中,经常可以看得到程序员的自我反省,比如有这样的注释:
// TODO - Fix me please! // Hack! This is nasty - if two sessions are created within a short ...
不管是设计、编码还是接口定义,追求清晰、简洁,追求其中之美,似乎正是给追求卓越的程序员以精益求精之导向的方式。
文章未经特殊标明皆为本人原创,未经许可不得用于任何商业用途,转载请保持完整性并注明来源链接 《四火的唠叨》
程序员也是艺术家,只不过我们认知范围内的艺术家的作品会比较直观,程序员代码之美很多时候只能自己欣赏