今天突然想到两个有意思的问题:程序与软件有区别吗? 编程与软件开发有何区别?
这两个问题也是我在大学时期一直思考的两个问题。作者在学校期间阅读了许多的专业书籍,比如《Java语言程序设计》、《C语言程序设计》、《软件工程》、《设计模式:可复用面向对象软件的基础 》以及许多《21天精通XXX程序设计》系列书籍,也写了许多的小程序,但有一些问题作者始终没有完全弄清楚。比如:
1.真的可以在21天之内精通某一门程序设计语言吗?
2.什么是面向对象?
3.Java语言为什么要提供接口,为什么要将接口定义和实现强制分开?
作者在学校期间曾向老师请教过这些问题,得到的答案要么照本宣科,要么含糊其辞不得要领。直到工作多年之后作者才明白,有许多问题是无法在学校得到答案的,必须要等你真正进入这个行业之后,才会慢慢明白其中的道理。 好的老师与差的老师区别在哪里:好的老师总是能用最简单的方式给大家解释清楚最复杂的问题。下面来谈谈上面的几个问题:
1.真的可以在21天之内精通某一门程序设计语言吗?
从开始学习计算机到现在已有8年时间,但是工作中遇到的难题仍然比比皆是。每当读到James Gosling、Rod Johnson这些大师的经典著作时,才发现大师的高度难以企及。想想当初找工作在简历上写精通XX语言时,难免汗颜耳赤。
2. 什么是面向对象?
在学校期间,计算机课程的老师会引用各种比喻来解释什么是对象。比如:你是对象我是对象世间万物皆是对象;类和对象的关系就像学生和王小明的关系、飞机和波音737的关系等等等等。大家听完还是云里雾里。其实在了解面向对象之前,我们应该了解两个概念:数据结构中的抽象数据类型(Abstract Data Type)和C语言中的结构体(struct)。在了解这两个概念之后,相信大家对面向对象应该有更清晰的了解。面向对象无非是抽象数据类型(Abstract Data Type)实例化,也是结构体(struct)的升级版。很多人容易被面向对象这个概念搞晕往往是因为面向对象这个概念被滥用或者过度解释所致。无论是结构体还是对象,都是用来组织和传递数据的。当软件规模越来越庞大时,模块化是必然的选择。面向对象可以帮我们更好的实现模块化。
3.Java语言为什么要提供接口,为什么要将接口定义和实现强制分开?
如果一个软件的全部功能都能在一个文件中来编写实现,那显然我们不需要接口,也不需要面向对象和类,更不需要package包这些玩意。但是软件规模的增长速度是惊人的,软件功能越来越强大,体积也越来越庞大,这是谁也无法阻挡的趋势。把软件划分成不同的模块,让不同的类去实现不同的功能,让一个类去调用另外一个类的方法来完成业务,这是通行的做法。但是这种强引用会带来一个严重的问题:耦合度太高。有一个成语可以形容这种情况“牵一发而动全身”,某一处的小改动会导致所有地方受到影响。但是软件需求的变更、功能的增加、数据的调整,这些是我们每天都会面对的事情。而接口实际上将调用方和实现方强制分离开,实现的变更对调用方不会产生影响,降低了模块之前的耦合度。
4.什么是异常?异常处理机制可以保证我们的程序永远不出错吗?
笔者记得上大学时,老师对着Java异常类层次结构图大讲特讲,但最后大家对异常的概念总是一知半解,写程序时try-catch总是用的不对。其实异常简单点说就是逻辑错误。我们编写计算机程序实际上是我们逻辑思维的具体符号化,但是逻辑难免会存在缺陷,程序也是如此。编写程序就像我们焊了一个电路,只有通上电某个地方冒烟了,你才知道这里存在bug,这种情况就是出现异常了。写代码时出现编译错误那不叫异常,编译器可以帮我们指出语法错误,但是编译器无法帮我们解决异常。比如我定义了一个对象,调用了对象的一个方法,但是在运行环境中这个对象却不存在,这个时候就出现了空指针异常。如果没有异常处理机制,程序会中断退出,或者进入非正常运行状态。运行时异常是非常常见的,我们当然不希望我们的程序出现任何一点异常就崩溃了。所以异常处理机制对于提高我们程序的健壮性有着重要的作用。
再回到开始的两个问题:
1.程序与软件有区别吗?
我们在大学实验室写的代码并不能称之为软件,而只能叫做程序。软件是为了解决用户的需求,而程序往往没有特定的用户。是否经过测试达到一定的质量标准,这也是程序和软件的差别之一。文档和代码对软件来说同等重要,而程序则对文档基本没有要求。
2.编程与软件开发有区别吗?
这个问题跟上面的问题本质是一样。我们在学校实验室写了一段程序和我们在公司为客户开发软件区别在哪里呢? 在实验室写程序不用面对客户多变的需求,也不用担心程序的版本升级问题,也不必过多考虑程序的容错性和健壮性等等。我想这就是编程和软件开发的差别吧。也正是这些源源不断的问题推动着技术向前发展,我们也在解决问题中不断提高。