|
首先,在写这篇博客之前,我已经从事程序员行业接近2年时间,而推出这篇软文的最大意义算是反思跨入程序这个行业的所思所想。软件开发过程更多地是一个复杂(Complex)问题。在一个产品被开发出来之前,不确定性非常高,团队(包括业务人员和技术人员)对产品的知识也是最少的,而且需要大量的学习和尝试才可以明确下一步可能的方向。不幸的是,很多时候我们需要在一开始(不确定性最高的时候)就为项目做计划。这种从传统行业中非常适合的方法在软件开发领域不再适用,这也是敏捷开发、精益等方法论在软件开发中更加适合的原因。 简单的举一个例子吧: 需求的变化方向 作为程序员,有一天你被要求写一段代码,这段代码需要完成一件很简单的事: 打印”Hello, world”5次 很容易嘛,你想,然后顺手就写下了下面这几行代码: print("Hello, world") print("Hello, world") print("Hello, world") print("Hello, world") print("Hello, world") 不过,拷贝粘贴看起来有点低端,你做了一个微小的改动: for(var i = 0; i < 5; i++) { print("Hello, world") } 看起来还不错,老板的需求又变成了打印”Goodbye, world”5次。既然是打印不同的消息,那何不把消息作为参数呢? function printMessage(message) { for(i = 0; i < 5; i++) { print(message); } } printMessage("Hello, world") printMessage("Goodbye, world") 有了这个函数,你可以打印任意消息5次了。老板又一次改变了需求:打印”Hello, world”13次(没人知道为什么是13)。既然次数也变化了,那么一个可能是将次数作为参数传入: function printMessage(count, message) { for(i = 0; i < count; i++) { print(message); } } printMessage(13, "Hello, world"); printMessage(5, "Goodbye, world"); 完美,这就是抽象的魅力。有了这个函数,你可以将任意消息打印任意次数。不过老板是永远无法满足的,就在这次需求变化之后的第二天,他的需求又变了:不但要将”Hello, world”打印到控制台,还要将其计入日志。 没办法,通过搜索JavaScript的文档,你发现了一个叫做高阶函数的东东:函数可以作为参数传入另一个参数! function log(message) { system.log(message); } function doMessage(count, message, action) { for(i = 0; i < count; i++) { action(message); } } doMessage(5, "Hello, world", print); doMessage(5, "Hello, world", log); 这下厉害了,我们可以对任意消息,做任意次的任意动作!再回过头来看看那个最开始的需求: 打印”Hello, world”5次 稍微分割一下这句话:打印,”Hello, world”,5次,可以看到,这三个元素最后都变成了可以变化的点,软件开发很多时候正是如此,需求可能在任意可能变化的方向上变化。这也是各种软件开发原则尝试解决的问题:如何写出更容易扩展,更容易响应变化的代码来。
|