耶稣就打发两个门徒,对他们说:“你们往对面村子里去,必看见一匹驴拴在那里,还有驴驹同在一处。你们解开,牵到我这里来。若有人对你们说什么,你们就说:‘主要用它。’那人必立时让你们牵来。” 这事成就,是要应验先知的话,说:“要对锡安的居民说:‘看哪,你的王来到你这里,是温柔的,又骑着驴,就是骑着驴驹子。’” 门徒就照耶稣所吩咐的去行,牵了驴和驴驹来,把自己的衣服搭在上面,耶稣就骑上。 
                                                                       《马太福音》 21:2-7


数学家说,这个世界是个数字的世界,那么程序员会说这个世界是数据的世界。程序就是对数据的处理。在软件开发的众多分支领域中,Web开发是主流。出乎其外,跳出Web开发看Web开发,纵观Web应用组成,大体可以分为三部分。第一部分是数据库,主要负责数据的增、删、改、查。第二部分是浏览器,主要负责数据的展现、浏览。第三部分就是Web应用程序,夹于数据库和浏览器之间,主要负责根据浏览器发过来的请求,到数据库中去对数据库中的数据进行增、删、改、查,并且将处理结果返回给浏览器。
数据库有专门的厂商,有诸如Oracle、DB2、MySQL、SQLServer等成熟的产品。浏览器也有通用的IE、傲游等。这两部分基本上不用Web程序员关注太多,重点是关注Web应用程序这部分。其中,Web应用程序是运行在Web容器中的。此外,Web容器也是有成熟的产品。Java方面的诸如WebSphere、JBoss、Tomcat等。如此盘算下来,Web程序员主要工作仅剩下负责Web应用程序的开发。当然,因行业不同,需求不同,这部分是变动最大的,最灵活的。
整个Web开发,可以用现实生活中的物流来做比喻。如果数据比作现实生活中的货物的话,那么浏览器则类似于现实生活中店面里的柜台,数据库则类似于现实生活中的仓库。不必多想,Web应用程序就类似于夹于柜台和仓库之间的运输车了。就像Web应用程序负责请求查询数据一样,运输车负责根据店面销售需求从仓库中提取货物。就像Web程序负责存储数据一样,运输车也负责将店面多余、暂时不用的货物运输到仓库。
无须大惊小怪,从这个角度来看,Web程序员就类似于钻在汽车底下面、全身脏兮兮的汽修工了。与之不同的是,汽修工可能在室外工作,程序员在室内干活;汽修工用的是钳子和扳手,程序员用的键盘和鼠标;汽修工面对的是汽车,程序员面对的软件;汽修工可能在流水性上批量生产汽车,程序中大部分是定制系统。客户需要时,找来几个"汽修工",启动一个项目,定制出一辆"新车"。需求不同时,车型也不一样。如果是个人用的,注重美观,可能造一辆大众或宝马;如果是短途的,又是小量的运输,可能就造一辆面包车;如果是拉煤的,又是长途,可能就要造一辆火车了。车造好了,一直在跑,偶尔难免抛锚、出故障等。刚开始可能出现的问题小,频率低,时间一长,零件慢慢老化,问题就大了,频率也高。这个时候就轮到汽车修理工干活了。

Web程序员难道不就是天天在做着这些事吗? 汽车造好了,客户买回了家,就一直在用。系统做好了,上到生产环境,一直在运行。随着时间的推移,数据库中数据越来越多,到一定级别时,表中数据量达十万级别,百万级别,甚至更多,系统性能开始慢慢降低。另外,客户在使用的过程中,发现某个现有的模块需要改动,或者要在当前的系统基础上添加新的功能。日积月累,时间长了,系统像那在马路上已经跑了数年的汽车,因为年老气衰,跑一阵子就喘口气,咳嗽几声。搞不好,又得送进维修厂折腾一阵子。可幸的是,汽车破烂了,主人有钱,就可以买新的,让旧的退出工作岗位。软件系统就不一样了,“改头换面”不是轻易而举的事,哪怕客户再有钱也不行。系统一旦上线了,有了生产环境的数据,则每一次变动,都得在原来的设计上更改。系统就像人的身体,是一个有机的整体,这一层调那一层,这一方法调用那一个方法,事先都约定好了。系统设计做得好,免疫力强,患个小感冒、或摔了一跤磕破了点皮,无关大碍。可大的变动,就像要换一支胳膊、或换一条腿,系统设计再灵活也难以支持。即使支持也得付出沉重的代价。 或许,从这一点来看,汽修工比程序员更幸福些。

程序语言翻译

数据库,其实也是个软件。术业有专攻,数据库就是一个专门用来管理数据的软件。这管理就类似于现实生活中的仓库。仓库可以往里面存储货物,也可以从里面取出货物。具体的存储和取出,由仓库管理员来设计和协调。另外,时不时出于管理等需要,还需要做出些统计报表。与其类似,数据库主要作用就是对数据进行增、删、改、查。具体的操作,也有数据库管理员。
两者虽然类似,但仍有些不同。第一,仓库里的货物无法备分,数据库里的数据可以备分,而且一般都会作了备分。第二,仓库可以看得见,包括里面的货物也都是肉眼所能见的。数据库一半看得见,一半看不见。数据库里有数据,但不可能直接打开存储数据的文件,必须得在客户端执行指定的命令才能看见,所以说数据库“是一半看得见,一半看不见”。正因为不能完全看见,操作起来才更有难度,需要一定的理解能力、抽象能力,通俗的说,更注重脑力,而非体力。仓库管理,因为货物都为可见物,对脑力的注重相对来说少了许多,对体力注意的多些。因此,有了第三个不同,数据库管理员的收入普遍比仓库管理员高,甚至高出几倍。

代码清单1:Storehouse类源代码

/** * 发生在物流世界里的故事 */ package logistics;

/** * 仓库,主要负责货物的存储和取出 * 相当于数据库部分 */ public class Storehouse {

/**
 * 仓库管事员
 * 说明:这个角色类似于软件开发中的数据库管理员
 */
private String administrator;

/**
 * 传呼仓库管理员
 * @return
 */
public String getAdministrator() {
    return administrator;
}

/**
 * 指定仓库管理员
 * @param administrator
 */
public void setAdministrator(String administrator) {
    this.administrator = administrator;
}

/**
 * 有仓库,一般就有仓库管理员
 * @param administrator
 */
public Storehouse(String administrator){
    this.administrator = administrator;
}


/**
 * 存储货物
 * @param goods 货物
 */
public void storeGoods(String goods){
    System.out.println("把货物分门别类放到仓库里指定的位置存储起来。");
}


/**
 * 取出货物
 * @param location 货物存储的位置
 * @return 返回取出的货物
 */
public String getOutGoods(String location){
    System.out.println("按着指定的位置,从仓库中取出相应的货物。");
    return "货物";
}

/**
 * 按照要求统计仓库货物
 * @param 统计的需求
 */
public String statistics(String request){
    System.out.println("仓库管理员按着统计需求,根据库存实际情况做成报表。");
    return "统计报表";
}

}

应用软件一般是定制的,但细化到具体的行业,各个行业的行业特性大体上是固定不变的。因此,有些公司摸索出行业的特色,开发出了适合这个行业的通用型的应用软件,作为产品在市场上销售。对于这种就如同汽车厂里根据市场情况分析,预先研发、并且批量生产了一款类型的汽车。对于那种定制的,则类似于客户相不种批量生产的,直接跟厂商说出要什么样类型的汽车,厂商再为他定制。(当然,事实上汽车行业里,这种定制情况极少,但如果客户很有钱,出价高,那就另有别论了。) 不管是批量生产,还是定制,出来的厂品都是车。作为要和仓库打交道的车一般比较憨厚、实在,甚至被专门取了个通用外号,叫货车。货车没有小轿车那般的浪漫,今天从这个地方“轻轻的我来了”,明天又在另外一个地方“空空的我走了”。相反,倒是更像臧克家笔下的《老马》。

                        老马
                                        臧克家

总得叫大车装个够, 他横竖不说一句话, 背上的压力往肉里扣, 它把头沉重的垂下!

                 这刻不知道下刻的命,
                 他有泪只往心里咽,
                 眼里飘来一到鞭影,
                 它抬起头望望前面。

“鞭影”来了,老马就抬起头来“望望前面”,不管大车有没有装得太够,“背上的压力往肉里扣”,同时还毫不抱怨,“横竖不说一句话”。同样的,货车也是这般的性格,这般的命运。销售火爆了,加班加点的运。销售淡季了,又重新往仓库运。销售市场的风“不知道往哪一个方向吹”,所以货车也是“这刻不知道下刻的命”。就这样,肉体和心灵的双重压力担在身上,用不了多久,很容易未老先衰。庆幸的是,司机可以平时好好保养,其间问题时也可以找汽修工。 Web应用程序就相当于这憨厚、老实的货车。作为程序员的你,如果同情这老马般命运的货车,平时在工作中就多多照顾它吧。

代码清单2:Truck类源代码

/** * 发生在物流世界里的故事 */ package logistics;

/** * 货车,主要负责在仓库和柜台之间实现货物周转运输 * 相当于程序员开发的Web应用程序 */ public class Truck {

/**
 * 货车司机。
 *(会开车的,一般多少会修车,只是缺少工具和要替换的零件)
 */
private String driver;

/**
 * 汽修工。(汽修工肯定会开车,也可做司机)
 */
private String repairman;

/**
 * 有事时,找来货车司机
 * @return 货车司机
 */
public String getDriver() {
    return driver;
}

/**
 * 给货车找个司机
 * @param driver
 */
public void setDriver(String driver) {
    this.driver = driver;
}

/**
 * 出故障时,找汽修工维修
 * @return
 */
public String getRepairman() {
    return repairman;
}

/**
 * 出故障时,给货车指定维修工
 * @param repairman
 */
public void setRepairman(String repairman) {
    this.repairman = repairman;
}    


/**
 * 货车和司机是绑定在一起的。买了货车,肯定会有司机开
 * 说明:在软件开发中,自己做的程序肯定会用,首先肯定会使用;
 *         其次,熟悉内部实现,有毛病时知道问题原因在哪,知道怎么改。
 *         可以做"司机"去开"货车",但从角色上看更类似于汽修工的角色。
 * @param driver
 */
public Truck(String driver){
    this.driver = driver;
}

/**
 * 主要任务:在仓库和柜台之间来回运输货物
 */
public void transportGoods(){

}

生产是为了销售。与此类似,技术带来信息化产品最终也是为了服务于业务需求。简而言之,即为“技术服务于业务”。工厂里生产出来的产品的好坏,实验室里的研究报告或许并不能说明什么,结果最终要靠消费者说话。毕竟消费者的眼睛是雪亮的。同样,在软件开发中,设计做的多么好,用的技术多么先进,客户可能并不关注,他们注重的是最终的软件产品。业务需求是否已经满足,查询和提交的速度是否足够快,以及页面是否美观等。

代码清单3:Counter类源代码

/** * 发生在物流世界里的故事 */ package logistics;

/** * 柜台,主要负责于展现货物,和发出调取货物的需求 * 相当于Web程序中的浏览器部分 */ public class Counter {

/**
 * 展现货物
 */
public void display(){
    System.out.println("按着货物类别,分门别类摆好,向消费者展示。");
}


/**
 * 发出调取货物的需求
 */
public void sendGetGoodsRequest(){
    System.out.println("根据销售良好和店面的现有货物数量不足,发出提取货物的需求!");
}

/**
 * 发出存储货物的需求
 */    
public void sendStoreGoodsRequest(){
    System.out.println("根据销售情况欠佳和店面的现有货物过多,发出存储货物的需求!");
}

}

enter image description here