如何编写优秀软件
作为每一名程序员,都希望自己能编写出非常优秀的软件,而要写出好的软件,并非易事,需要有良好的编程习惯,一流的技术水平和丰富的实践经验。作为北大青鸟的一名老师,我一直从事着ACCP课程的教学工作。通过多年的开发经验和教学经验以及在学生中发现的问题,我现在来谈谈软件开发,希望能帮助各位学员编写出优秀的软件,成为出色的软件工程师。
1、 需要的便是最好的。对于公鸡来说,麦粒胜过钻石。
需要的东西才是最好的。对于公鸡来说,钻石对它没有任何价值,它不能吃,也不能用。而对于人来说,钻石可能非常有用,因为我们需要。
那么什么样的软件才是最好的软件呢?需要的便是最好的,满足用户需求的软件才是最好的软件。我们开发软件的时候一定要以用户为中心,为用户设计软件。而不要站在自己的角度来设计软件,更不能更改用户的需求。
有些学生在考试的时候,更改试题的题目,不按题目要求来做,这是非常错误的。我跟他们说,试题就是用户的需求,如果试题要求的你没有做,就不能得分,做多了不能加分。同样,用户要求你开发一个软件,你没有按照他的要求来开发,他不会给你钱,你开发了多余的功能,他也不会多给你钱。我们开发软件,一定要按照用户的要求来开发,需要的便是最好的。
开发软件一定要以用户为中心,不要以自己为中心。你是为用户开发软件,软件是卖给用户的,不是卖给你自己的。所以你觉得好不一定好,只有用户觉得好才是好软件。一次答辩会上,一个学生的界面用鲜艳的颜色做背景,我觉得不太合适,我就问:“你项目中的背景颜色合理吗?”,他说:“我觉得很好看”。很明显,这样的软件一定是失败的,他不是站在使用者角度看问题。同样在答辩会上,有些学生讲解项目的时候,如果是可视化的项目,一个菜单一个菜单的讲,如果是Web程序,一个网页一个网页的讲。如果你是以设计者的角度来讲解的话,只有你自己能听懂,也只有你自己可能愿意听。我们应该站在使用者角度来讲解项目。比如我要讲解一个网上书店,先打开主页,然后分类浏览,浏览后可能要搜索书籍,加入购物车,登录,注册,下定单等等。用户怎么用,我们怎么讲,这样用户更容易理解。
2、 提高软件的可读性。
很多程序员都知道,如果软件没有可读性。那么就无法协同开发,因为别人无法阅读你的代码。同样软件没有可读性,可能过一段时间自己都看不懂自己写的代码了,这样的代码可能就成了一次性代码,再也不能修改和使用了。
怎样提高软件的可读性。有经验的编程人员会告诉你:使用规范的命名,合理的分层结构,完整的文档及注释。我不会这样跟你说,因为检验软件可读性的标准不仅仅是这些。那么我告诉你,要想让你的软件具有很好的可读性,你应该这样做:把你的代码给你班上的所有同学和老师阅读。如果他们能够看懂,那么你的代码具有很好的可读性。如果连老师都看不懂,那么你的代码可读性就非常差。同样,作为程序员要有很好的沟通能力和语言表达能力。那么怎样训练自己的表达能力以及知道自己的表达能力是否过关呢?当同学遇到问题,给同学讲解,如果他能听懂,说明你的表达能力不错,如果所有人都听不懂,你的沟通和表达一定存在问题。我们把自己的代码给其他人看,一方面可能检验自己的代码是否具有可读性,另一方面也可以帮助其他同学。同样,同学有问题我们帮助讲解,一方面可以提高和检验自己的表达能力,也能帮助其他同学学习知识。记住:帮助别人就是帮助自己。一个晚上一个瞎子提着灯笼,路上一个行人看到这个瞎子对他说,你一个瞎子,提着灯笼干什么,又看不见。瞎子说:我提着灯笼,是为了照亮别人,让别人看清楚,以至于不撞到我。帮助别人就是帮助自己呀!世界级软件大师Eric Gamma(设计模式之父、JUnit设计者、Eclipse架构师)说的好:“我们每个人都需要别人的关怀和帮助,每个人也需要关怀和帮助别人。”
3、 具有良好的复用性和灵活性。
使用面向对象的开发技术,能很好的支持复用性和灵活性。封装和继承是用来复用的,多态是用来实现灵活性的。
复用非常重要,可以开发大型应用程序。我们到处可以看到复用技术,封装是让变动的事物和不变的事物彼此隔离,不变的事物就可以复用了。而继承很明显在复用基类代码。框架技术也是在复用,用户控件是在复用,母版页是在复用,三层结构也是在复用代码。复用不是复制。复用是重复调用,复制是到处拷贝代码。复用是很好的,复制是很差的。
用户的需求经常变化,那么怎么提高软件的应对变化的特性(也就是灵活性)。多态性是用来实现灵活性的。我举一个接口的例子,在Java和C#中都有接口,为什么要使用接口,为什么要用接口作为方法的参数。在计算机中我们可以看到USB接口,那么为什么用USB接口呢?因为使用USB接口后,就可以连接所有使用USB接口的设备了,今天你可以接打印机,明天可以接鼠标,后天可以接移动硬盘,再后天你可以接数码相机,只要它们是USB接口的。所以接口可以根据你的变化来适应你所需要的设备,程序中的接口一模一样。如何能根据用户的变化做出快速的反应呢?这就需要我们的软件写的灵活。现在我们听说的敏捷软件开发也是如此。何为敏捷,在环境变化的情况下能快速的做出反应叫敏捷。
所以我们应该深入的理解面向对象的思想,提高程序的复用性和灵活性。
4、 高强度的测试,保证软件的健壮性。
很多人不重视软件测试,认为测试是在浪费时间。那么我告诉你,在软件开发中,几乎所有人都会参与测试,但不是所有人都会写代码,系统分析师对软件功能最了解,他会做系统测试,软件设计师对模块与模块的关系最为清楚,他会做集成测试,程序员对自己写的代码最清楚,他会做单元测试(或叫模块测试)。测试人员还会做专门的测试。如果没有进行很好的测试,软件在使用过程中出现了问题,以后别人可能再也不使用你的软件了,测试是保证软件质量最关键的一个因素。对于测试我们要注意以下两点:(1)尽可能早的做测试。测试越早,发现问题也越早,那么问题也更容易解决。(2)尽可能多的做测试。测试的用例越多,发现的问题也越多,使用的时候出现的问题也就越少,软件的质量也就越高。
如果软件没有进行有效的测试,你既得不到功劳,也没人欣赏你的苦劳,你获得最多的将只是疲劳。
为什么软件要有健壮性?对于一个人你肯定不希望自己长得非常的肥胖,因为这样做什么都不方便,效率会非常低。长得太胖,是因为有多余的肉,而对于程序就是多余的废代码,很明显废代码多了,会影响程序的执行效率的。同样一个人长得太瘦了,什么事也干不了,还可能经常得病,哪个公司也不愿意要这种人。而对于程序,代码太少了,实现不了功能,而且可能因为没有进行异常处理造成运行不正常,这样的软件谁也不愿意使用。我们需要的人是长的非常健壮的人,做事效率高,不生病,看起来身体均称。而对于代码,执行效率高,不出错,代码有很好的可读性。
5、 学习解决问题的方法而不仅仅是知识本身。
很多学生学习编程是靠记忆,这是非常错误的,一个人在一年中80%的知识是会忘记的。我可以跟大家说,我的记忆力是非常差的,但是我记住的东西是不会轻易忘记的。因为我是靠理解记忆。而且对于每一项技术,我会去深入的理解,所以我记忆的非常深刻。
好,我们举个例子,你看我怎样理解。在学生学习Java的时候,我会问学生==号是比较地址相等还是值相等。大部分学生回答地址相等,有的学生回答值相等。我说:“全错”。很明显,他们没有理解。值类型变量存放的是数值,引用类型变量存放的是对象的地址。那么两个值类型变量比较肯定是比较值相等了,你说3==5是比较地址相等吗?引用类型变量因为存放的是对象的地址,那么相等比较当然是地址相等了。
学生学习自加运算符++时,有一次晚自习,班长给学生辅导,问所有学生,5++等于几?所有学生都说等于6。幸好被我听到。我相信他们都知道++是将自己加一,也都能分清楚变量和常量,可是合在一起运用都不知道了,但是你跟他们一讲,他们都会理解,而且会理解的非常深刻。我对学生说:“5++是错误的。不能这样用。自加是改变自身的值。而5是一个常量,常量的值是不能改变的。这不是自相矛盾吗?所以自加和自减运算符只能用在变量上”。
6、 遇到问题不可怕,关键在于你是否能解决问题。
很多学生去参加面试,回来后非常不解的跟我说,面试单位给我出了个程序或者小项目,要我做完了过两天再拿给他看。这不相当是开卷考试吗?我跟他说,如果我是一个面试官,我也会这么做。因为我看重的,不是你记住了多少知识,而是你能解决多少问题。因为每个人都会遇到问题,老师也是如此,遇到问题不可怕,我们可以看书,可以上网查阅资料,可以问其他人,只要问题解决了,就非常好。