编程是门艺术,这个说法由来已久。最近在朱赟的公众号(嘀嗒嘀嗒)读到一篇文章《设计是门逻辑学,而后才是美学》,文中做者漂洋过海追寻艺术,老师却说:“设计不是艺术!”。若是设计都不是艺术,那么编程还能是艺术么?程序员
那么艺术究竟是什么?我一下懵了,发现历来没有想过这个问题,只好求助于 Google。Wikipedia 上的定义是:「艺术是具备智能思考能力的动物(目前其实只有人类吧),借由各类形式及工具借以表达其情感与意识形态,所产生的形态泛称之为艺术。」算法
而上面那篇文章中老师的观点是:编程
设计是实现别人的须要,艺术是自我表达的须要。设计模式
和 Wikipedia 的说法相近,核心都在于表达。而目前公认的艺术分类,包括八大艺术种类:微信
它们的共性是这些都是人类自古以来的创造,其中最年轻的艺术门类当属「电影」了,其做品承载了做者的情感和意识形态。而全部被公认的艺术门类,显然它们最终做品呈现出的艺术表达形态更容易被普通人直接的感觉到,直接做用于人们的视觉、听觉和触觉感官。架构
关于编程是一门艺术这个概念,到底何时钻入程序员的头脑中的呢?也许来自咱们在学习编程的路上,不少讲述编程的书籍都冠以艺术之名,好比:《UNIX编程艺术》,这是一本讲述 Unix 专家们在创造 Unix 过程当中造成的理念和文化,那么技术文化是艺术么?还有另外一本程序员中的圣经《计算机程序设计艺术》,咱们都知道,却几乎没读过。这是一套讲述算法,并基于数学来推导和论证算法的基础书籍,那么算法是艺术么?编程语言
编程的直接产物是代码,代码是面向程序员的,而非普罗大众。编程的间接产物是信息产品,在当下这个信息时代,信息产品的形态不少样化,能够是你手机上的 App,也能够是你每晚打开的电视。极可能一切和电子相关的东西,在当下或多或少都和编程有关,但咱们发现即便是在这些间接产物中,也找不出同样可让咱们很严肃的把它归为艺术。即便是神化的乔布斯时代,咱们给予的最大赞誉也只是苹果的每件产品都像艺术品通常。仅仅是像,像能够无限逼近,但毕竟还不是。模块化
因此相对而言,编程也如设计是实现别人的须要,像我在这写做倒更可能是自我表达的须要了。编程受限于程序语言的表达能力,是不可能达到像天然语言的表达能力的,所以编程的艺术性,它的受众也只多是程序员们。虽然面向大众的艺术,不少大众也表示看不懂,但至少能感觉,而编程艺术则是只有程序员自己才可能感觉获得了。工具
程序员的平常编程工做就是编写代码,完成功能,实现别人的须要。在这个过程当中不当心就还会制造一些 bug,程序员也不知道这些 bug 是怎么变出来的,就像你每天在家作饭,不知道怎么厨房里就多了那么多小强。美食也不属于公认的艺术门类,但时不时咱们会听到美食艺术的说法,这一点却是和编程艺术很像。但如果你在创造美食的过程,时不时冒出些小强,哪里还有去感觉艺术的心思。程序员大部分时候就是在不断的解决绵绵不断,生生不息的 bug,这个过程与艺术无关,只与技术有关,技术越练越好,bug 也就愈来愈少。bug 少到咱们能腾出精力和心思,才能去感觉编程的艺术性。单元测试
编程的艺术源于技术,没有技术则艺术成了无源之水,无根之木。因此那些冠以「艺术」之名的程序书籍其实都是讲的技术或者技术原则与文化。而关于编程最基础的技术固然是写好代码,而如何写好代码这件事之前看过王垠写过的一篇长文《编程的智慧》,其中观点我都认同,包括下面一些方面:
文章很长,但花点时间细细读来,必有收获,其中关于推敲代码这点于我感触最深。
看一个做家的水平,不是看他发表了多少文字,而要看他的废纸篓里扔掉了多少。我以为一样的理论适用于编程。好的程序员,他们删掉的代码,比留下来的还要多不少。
我曾经本身维护了一个项目,包括一些样板代码,称手的小工具等等。每年我都会抽业余时间对这个工程作一次重构,一些代码随着技术发展而过期了,一些则被从新实现变得更简洁。每一年的一次回顾,对过去本身的审视,对代码的推敲都带来新的成长,这个过程持续了大约七年。
在技术成长到了必定阶段,有些程序员就会开始不知足于仅仅实现别人的须要,也会在代码里尝试自我表达。最基础且最明显的表达是为代码签名,打上本身的标签,要是雷军二十年前没有为那段汇编代码签名,咱们今天哪里知道这会是雷军写的,并在这里评头论足。但依然有不少程序员不会为本身的代码签名,连机器生成的代码都会签名说这是自动生成的,而一份没有签名的代码是缺少艺术最基本的要素「自我」的,永远停留在艺术的门槛以外。
另外一些程序员则不止于此,好比 Redis 的做者 @Antirez,你会在 Redis 启动控制后台看到下面的启动画面,这个程序字符精心打印出来的 Logo 无关乎任何功能和别人的须要,只是做者的自我表达而已。
而另一段代码中,单元测试经过后的输出中每一个 case 会有一个笑脸,在调试代码的寂寥中增长点点暖意。
进一步回归到源代码自己,代码同时是主观的和非主观的。编码非主观的方面就包括一些建立好代码必须遵循的「硬」规范:设计模式,项目结构,公共库的使用等等。 虽然这些概念奠基了高质量、可维护代码的基础,但正是程序员间不一样的技术与工具的细微差异,微妙的风格选择——对齐方式、命名、空格使用、语境利用、语法高亮和IDE的选择——真正使代码清晰、可维护和容易理解,同时也使得代码更好的表达了其意图、功能和用法。
任何人均可以遵循设计模式或其余一些「硬」规范来编写代码,但有艺术追求的程序员会以本身的方式来填充代码的细节,使代码变得清晰、简洁、易懂。 这很重要,正如每一个人均可以从一件艺术品中体会到独一无二的意义,无论代码的架构和设计怎样,每一个开发者或代码阅读者可能也会从代码的命名和其余约定习俗中推断出不一样的含义。
就像上面一段对得整整齐齐的代码声明块,没有语法或硬性的风格要求程序员要这样写。我只是以为这样更符合视觉感觉,更容易清晰分辨。而这一点 Poul-Henning Kamp 曾在 ACM Queue 发表文章提出了一个迷人的观点:
不少编程语言的风格源自于 ASCII 字符集和基于打字机的终端。编程语言没有利用现代设备的图形属性和选项。虽然代码是按照清晰的英语语法格式编写的,但它并非英文句子。事实上,它更像数学和表格。
而有时还会有些看起来明显不符合「好」代码规范的代码编写方式。
上面的代码中, if
语句后面把多句代码写在了一行,但从总体上看这样一个短小的方法,其表现形式一下就能让阅读者捕捉到,方法内部有四个分支,每行代码一个分支状况,两种正常分支,两种异常分支。
上面这些随手拈来的例子,都是做者有意为之的选择,正是在这些微妙的我的风格选择中,体现了做者自个人表达。
单独说编程艺术是不完整的,编程是从技术走向艺术。编程艺术是开在枝头的鲜花,而技术是支撑花朵的枝与根。
而在技术和艺术之间实际存在一道很高的门槛,艺术是一种自我表达,但自我表达却未必是艺术。关于这一点咱们说个你们耳熟能详的人——毕加索,他说:
我十多岁就能画的像拉斐尔那么好了。
毕加索到底有没有说过这句话,我没去考证,但他的做品至少说明了一些事实。拉斐尔是文艺复兴时期的写实派画家,他的素描和油画像是下面这样的(图片来自「顾爷」公众号,一个常常谈艺术颇有趣的公号)。
而毕加索十多岁时候的素描和油画是下面这样的。
写实是毕加索的绘画基础技术,而其后期的抽象主义才是他的艺术自我表达,二者相辅相成。
虽然,我也不太看得懂毕加索后期的抽象做品,毕加索相对于大众的距离依然比编程相对于大众的距离更近。编程的艺术之花也许就像花中的「满天星」,永远只是配角,只有追寻艺术的程序员方能感觉到满天星所营造的那份梦境吧。
…
编程是完成功能,编程是解决 bug,编程是打磨技能,编程是修炼心性,最后编程才成了艺术。
写点程序世间的文字,画点生活瞬间的画儿。 微信公众号「瞬息之间」,碰见了不妨就关注看看。