我所理解的软件工程
前言
我只记得初中的时候有计算机课,老师教我们玩FLASH,也就做一下补间动画,没用到AS。高中的时候上过一点点编程,用的是什么语言忘记了,当时就是做了个加减乘除的运算,大概类似
int a=1;
int b=2;
int c;
c=a+b;
print(c);
当时就照着老师给的代码敲上去了,得出了结果,让我有一丝兴奋,可是我百思不得其解,int是什么鬼,int a=1又是什么意思,为什么一定要这样子敲才行?询问老师,虽然老师的解答像是听天书,但是我还是觉得很神奇的。由于学业繁重,08年的时候信息网络还没那么发达(当时一个月30M流量根本用不完啊!),也没处深入学习,就这样没有然后了。
大一大二基本都是在学编程基础,当时班里有几个从小学就开始编程的同学,在我们心中简直就是神一般的存在,怪叔叔就是其中一位,很感谢他耐心的解答当时我提出的各种奇怪的问题(因为不懂,所以问的问题也很搞笑)。
大三大四才开始初步学习软件工程
,当然也都是在纸上谈兵,实践的时候大家也都是像过家家一样,不痛不痒,似懂非懂。
那到底什么才是软件工程?它与传统工程有什么不同?当初我总拿土木工程做类比,但是到最后发现并非如此。
软件的规模
也就在几十年前,计算机的硬件还是如此的low,导致我们开发的软件规模不可能太大,那么需要的人手也不是很多,大多数软件都是一个人完成的。多亏了摩尔定律,如今计算机硬件可以说多数情况已经不列入软件评估的范围了。于此同时,软件的需求也越来越多,规模越来越大,几个人不能完成了,怎么办?召集人手一起干!然而结果最终产出的软件产品质量不高,实际生产效率低下,从而导致了“软件危机”的产生。这迫使人们不得不研究、改变软件开发的技术手段和管理方法。软件工程
由此而来
软件的核心是人
我想这是软件工程与传统工程最大的不同
如果说软件的核心是机器,软件工程也不会是如此困难了,因为机器是可度量的,可操控的,就像流水线上的机器,你让它干一整天,它不会说生气不干了,并且每一台机器每天的产量是一样的。
但是软件开发是一个创造性的过程,也只有人类拥有创造性思维。
所以软件开发绝大部分是受到人为因素影响的,而世界上的每个人又不同,如何物色、管理、运用这些人?让他们发挥其最大的价值?
《人月神话》里也清楚的表述过,人越多,沟通成本越高,而每个人的技术实力又不同,如果一个大牛突然生病了,这个影响就很大了,所以你很难用人月来评估项目进度。
这是一个需要长期思考实践的过程(貌似无解,不然这么多年也不会停滞不前)。
软件大部分是看不见摸不着的
软件是人类智慧创造的结晶,只可惜它不像传统工程显而易见,当你拿着手机在淘宝上购买商品时,你看到的只是软件UI交互部分,指引你发生购买行为,但是整个过程涉及到的技术以及代码量,你是无法想象到的,就算给你源码看,难度也堪比登天。
这也就出现了让我们程序员啼笑皆非的提问
“开发一个像淘宝一样的APP需要多少钱?也就是显示商品,然后点击购买。”
这一时半会很真的很难评估……因为这里面涉及到太多东西了。所以软件评估量化真的很难,而且实现方法原理都有所不同,这也就说明了软件是高度复杂的。
这也就牵扯到一个问题,软件开发过程中的程序员不能随意更换,否则重新理解阅读软件源码和学习开发框架是有成本风险的,这也是为什么软件工程需要制定规范,撰写文档等等。
从某种意义上,软件工程更希望我们像一颗螺丝钉,坏了立马可以更换。
新的技术与方法
任何新的技术和方法都不会无缘无故出现,都是为了更好的服务于某一种活动。
我们熟知的面向对象,敏捷开发等各种方法,各种语言,各种框架,其实都是为了解决软件工程的难题。
所以,有时候我们不必盲目崇拜新的技术和方法,这都需要我们进行评估,你不可能用node.js来写CPU密集型的程序吧?如果项目组没人会go语言,我看还是用熟悉的语言吧,不然学习成本和风险太大了。
在给定成本、进度的前提下,开发出具有适用性、有效性、可修改性、可靠性、可理解性、可维护性、可重用性、可移植性、可追踪性、可互操作性和满足用户需求的软件产品。
这才是我们需要思考的问题。
软件工程过程
经过时间的历练,软件工程一般会有6个阶段:
1、可行性分析
“我想开发一个**系统,你看行不行?”
在我看来,目前任何技术上的问题,都不是问题……,所以这个过程经常讨论的是政策、法律、人员、资金方面的问题。
2、需求分析
“就开发一个类似淘宝的软件,你看多少钱?”
这样的问题是个深水炸弹,经验不足的新人总会不假思索的大概给个估价~,如果你估对了还好,不对就等着扯皮吧!
我遇到这样的问题,如果没有足够把握,一律会要求做一次详细的需求分析,待甲方确定了需求并且签字之后,最后进行才进行总体评估,当然,过程中变更是不可避免的,但是有这个需求确认单,可以减少很多扯皮的事情。
3、设计
这个阶段就比较考验技术团队了、其中包括系统架构师、软件设计师,对于技术选型,架构设计需要符合当前的系统需求情况,最好做到不多不少,刚刚好~对于日后用户数据规模变大之后,再进行二次架构变更,这个过程其实是需要演进的,很难做到一开始就设计出完全符合高软件质量的架构,并且每个特定领域都不一样,除非技术团队在这个领域已经有过多年大型开发经验。
在设计的同时,也要评估具体的项目时间进度,这玩意基本全靠经验(注意,每个人的生产效率都不一样),也许大牛这个模块1天搞定,分配到其他程序员,3天也搞不定,也许你认为1天可以搞定,可能3天也搞不定…,这时候开个会议进行分工,让相应的程序员自己评估也未尝不可(类似的方法也有很多)。
4.、实施
这个时候项目经理就起到了很大的作用了,需要把控好整个项目的实施过程。而我们程序员要做好的就是,按照设计规范写代码,做好注释,做好单元测试。
5、 测试
QA大显身手的时候到了,但是小公司基本上都是程序员自己测试,不管用什么测试方法,总之最后要求软件符合产品需求,不然就等着扣钱吧。
6、验收
甲方测试通过,就可以进入验收阶段了,各种文档的交付,软件部署,运维方案等等,但是这个阶段甲方总喜欢骨头里挑刺,也会再提一些修改要求,到这个阶段,总之要自己权衡了利弊,如果双方都满意那真实是皆大欢喜。
总结
3年了,做过外包,搞过产品,目前我对软件工程的理解就那么多,再来看一下公认的定义:
软件工程是研究和应用如何以系统性的、规范化的、可定量的过程化方法去开发和维护软件,以及如何把经过时间考验而证明正确的管理技术和当前能够得到的最好的技术方法结合起来。在给定成本、进度的前提下,开发出具有适用性、有效性、可修改性、可靠性、可理解性、可维护性、可重用性、可移植性、可追踪性、可互操作性和满足用户需求的软件产品。
目前的规模,软件在今后很难再是几个人开发的,而是由几十甚至几百人的团队进行。而人又很难进行度量。
所以我认为归根结底还是由于人为因素的不确定性,导致软件工程如此特立独行。
过了那么多年,我们还在寻找那一颗银弹,然而依旧还有很长的路要走呢。