您的位置:首页 > 其它

[随笔] 记在项目完成之后

2011-10-08 08:42 239 查看
随着项目规模的不断扩大,程序开发中存在的BUG和困难也几乎同比例增加,最后,开发人员会失去对项目的控制。当一切变得不可控,那么就可以给项目下达死亡判决书了。

----------------------------------------

于是,我经历了一次失败,接到了这样一份死亡判决书,因为我失去了对项目的控制,庞大的代码量让我无从梳理,无法向下推进,面对我亲手编写的程序,我束手无策。

…………

幸运的是,我从失败的阴影中走了出来。我依然热爱我的工作,并继续工作了下去。

失败是沉重的,但再失败又能坏到哪去呢,拍拍身上的灰尘,整理一下行装,大不了重头再来。

撰写此文,纪念我的失败,也总结我的心得。

理论与实际的差距有多远??

是否应该严格遵守教科书上的规范来开发程序??

如何让项目始终是可控的??

……

其实,这些问题,在死亡判决书上都有,如果你幸运的得到过一份,那么恭喜你,这是最好的教材。

一个值得思考的问题:

如何做好理论与实际的衔接。让理论不会束缚实际操作,而实际操作又不会偏离正确的理论。

我为什么会失败??

每次失败,应该从中提取致使自己失败的原因,不要做一个连自己死都不知道怎么死的人;每次失败,也应该从中提取那些可行的东西,并不是说失败的结果就意味着过程的全部失败。

我很幸运,因为我失败的很致命,这令我很容易找到我的错误。

下面讨论一个概念。

关于面向对象程序设计。

几乎所有的大学计算机课程都在教授OO的概念,并且我们习惯于拿着OO的概念高谈阔论程序设计。但有多少人在真正写程序,开发大型项目的时候,将OO的概念时装载在大脑内存里,攥在手心里???

一个简单的例子,请编写一个简单的计算器程序。

也许大部分程序员在设计该程序时采用过程范式,因为这太方便了,并且非常简单,谁也不愿意把一个简单的问题用复杂的方法解决。

一个复杂的例子,请为银行编写一个管理系统。

好吧,对于我们来说,可能谁也不会去考虑过程范式了。因为大家都学过,OO的思想可以提高大型项目的成功率。

但当进行这个大项目的开发时,你能保证每一步都面向对象么??

你会不会在编写某一个小的模块时,心里想:哦,这太简单了。于是写出了过程范式的代码。你会不会为了提高速度或者赶进度,而没有合理的抽象出对象,没有良好的分配对象的行为,没有优化对象间的交互。更甚者,你会不会根本不知道如何从银行的繁多复杂概念中抽象出对象。

于是你的项目里混杂着各种编程范式和思想,一切变得混乱,项目停滞。

所以,请从小例子做起,从简单的概念做起。

面对问题时,首先进行详细的思考,哪些概念可以抽象为对象,哪些数据应该作为该对象的数据成员,某些行为分配给这个对象到底何时不合适,如果设计了两个对象,他们之间的耦合度是否过大……

我觉得面向对象是一个厚积薄发的设计方式,在项目开始的阶段进度会非常缓慢,并且非常繁琐,因为作为设计师,你不能只想到第二步是个什么样子,而是你的对象组装起来后,最后一步应该是个什么样子,对象是否良好的工作,这中间过程是否合理并且灵活。

虽然开始阶段的设计会非常令人抓狂,但如果进行了良好的对象抽象,并保证了对象的良好交互,那么在后续的开发中你会开心的写程序都笑出来,那个时候,程序推着你前进,而不是你拽着程序在走。

但有一点也要时刻加载在你的大脑内存里,就是只要项目没有完结,就要不断的思考项目的面向对象设计,不断的完善和改进这些设计,考虑这种设计是不是更加灵活,对象松散度够不够。

因为你不得不承认有一种情况的存在,就是突然有一天早上你醒来,发现你的设计遇到瓶颈,存在严重BUG。或者你在喝咖啡,需求方打电话告诉你,不行,我们现在要这么做。

如果你每天都在思考,那么你立刻就能在脑子里重新组装你的对象,去掉一些,增加一些,改变一些交互,就可以组装出新的版本。

如果你没有思考,你会想不出来应该如何改进你的设计,你会心里说,完了,是不是要推倒重做??这帮混蛋。

在我看来,面向对象是模块化编程的进化,OO是一个优秀的概念,但还是那句话,要让概念或技术服务于你,而不是被它们束缚。

-----------------------------------------------------

那么我为什么会失败??我拿课本上的知识来设计和开发程序,每一步都力求合乎标准。

但理论是经过高度抽象的,并且忽视了很多细节问题,我当时并没有把理论揉碎了重新组装成真正属于我的知识,没有考虑到那些繁杂的细节,也没有考虑到很多客观的现实因素,于是我失败了。

比如一个很经典的数据库设计问题。

对于平地起高楼的我这是个悲催的问题,我需要分析需求方所描述的操作可能产生的一切数据。我得自己设计一种数据结构来保存这些数据,我得设计数据表来永久保存这些数据……哦,天呐,我想这个问题就足以导致我的失败了。

好了,开始思考,作为数据库设计人员,我用不用遵循数据库的设计范式??我需要设计成第几范式??我是不是要避免所有的数据冗余存储??我是不是要时刻考虑主键外键约束的问题??

如果你每个问题的答案都选择‘是’,那么恭喜你,你的第一次数据库设计将和我一样失败。

请在心里说,去他妈的设计规范,我只是要把数据存起来而已。

默念十遍,然后开始数据库的设计,你成功的几率就大了很多。

请不要把很多问题本末倒置了,对于数据库的设计,第一步应该是将数据保存起来,让数据能够方便的为程序服务。在此基础上,才应该考虑如何让数据存储变得更加高效,更加严谨。但永远记住,如果你对数据库设计的更改将会增加程序编写的难度,那么放弃这个更改,这一定是错误的。

有几点心得:

1、弄清楚你的程序里所有可能的数据字段后,再进行数据库设计。记住是所有的数据类型。

2、最好让你的每张表具有逻辑意义,它不应该仅仅是一堆字段的集合,而是应该能够代表一定意义,比如表中一条记录代表了一个对象的状态片段;比如代表了程序的一个运转片段等等。

3、分清楚静态数据和动态数据,并设计相应的表来存储他们。动态数据基于静态数据,并服务于静态数据(说明其状态)。

4、如果增加数据冗余存储可以方便程序的开发,那就这么做吧,但要控制好冗余度。

5、不断的完善你的数据库设计。

我不是专业的数据库设计师,我缺少必要的知识和经验,并且我要兼顾程序开发和数据库设计两个任务,所以我不会拿着课本的教条规范来设计数据库,我还负荷不了这样的设计任务。

失败的那段日子

失落,无奈,烦躁,并且失去信心,我甚至不愿意去看自己编写的那堆臃肿的代码。

也许我在使用理论指导项目开发时不够成功,但在我失败的时候,我却犯了教科书上讨论的几乎所有的错误。

我的OO概念用的一团糟,我设计的对象就像一个底盘不稳并且四个轮子不一样大小的汽车,无论怎么看都是个失败的作品。

我的程序耦合度很高,很难灵活的分离和重组,再怎么技术高超并且细心的师傅切一刀都会把程序直接咔嚓掉。

我设计的数据库,不伦不类,提取和分析数据就像便秘一样难过。

记住,随着项目规模的增大,开发中可能的BUG和问题增加的速度便会几倍于项目增大的速度。

记住,项目开发从来不是一个创造性的活动,虽然不排除某个细节的制作和实现非常的聪明巧妙,但整体来说,是要稳,再稳,还是稳。

记住,永远不要认为需求方不会再变更需求,并且永远不要抱怨需求变更。抱怨的心态只会令你的项目迈向失败。

----------------------------------------------

这里有一个值得探讨的问题,代码风格。

程序不可能永远完美的运转,不出错也不用升级。如果是这样,那就说明人类不再进步了,末路了。

所以为了方便后续开发人员的二次开发或维护,在代码编写和程序结构上,应该具有良好的风格。

甚至包括程序的注释风格,程序文件的存放结构,都是应该考虑在内的。

记住,作为程序员,我们创造的是自己的作品,排除一切厉害关系,这就是自己的作品,它应该精致、美观、内外兼修。

如果是团队进行项目开发,包括代码风格以及程序结构,都应该统一或者能够兼容,项目开始时首先就应该进行代码风格的统一化培训。这样在开发时,大家就可以在统一的标准下进行讨论。

关于项目的分类

项目分很多种,有些重点在于数据的处理和程序;有些重点在于对现实某些事件或过程的模拟,将现实计算机化。

不同的项目类型有不同的难度。所以第一,要认清自己所做的事情;第二,要认真对待自己所做的事情。

我为什么能够完成开发??

有两点,第一是我逐步摸索出了数据库设计的实用方法;第二是我在OO的概念上又有了长足的进步。

其实,如果你有了设计优秀的对象,并且有一个良好结构的数据库来存储这些对象(包括对象信息,对象行为产生的数据等),那么成功是必然的结果。

如果你有一个强大的数据库设计师,那么你的编码工作将非常愉快,你只需要告诉他,嘿,伙计,我需要提取这些数据,请把SQL语句给我。

然后你就只需要在程序里处理你所得到的数据。

可对我而言目前的情况是,我就是我自己的数据库设计师,我必须设计出良好的数据库结构,为自己的程序服务。

幸运的是,我把《数据库概论》的设计规范大部分都抛在了脑后,我只抱着一条原则,就是我的数据库为我的程序服务,而我的程序,为需求方服务,即精确模拟需求方的需求。

于是我幸运的成功了。

在这样原则的指导下,我的数据表具有一定的逻辑意义,虽然存在着数据的冗余存储,但一切变得非常清晰,降低了SQL语句的编写难度,减少了程序的分析量。

有了可用并且良好的数据库,再想起来那些设计规范并对自己的设计进行完善,记住那些牛人写的设计理论永远都是来完善你的设计的,而不是用来设计的。

--------------------------------------------------

OO的概念对我的帮助非常大,我有个建议,就是在系统学习过面向对象程序设计,并且考试通过后,当你面对程序设计时,也请将所有的设计规范抛到脑后。

设计师需要做的首先是经过对需求不断的思考,来抽象出可能的对象,并不断的完善。最后得到一组良好的、灵活的对象,能够完成需求方的当前需求,同时能够一定程度上接受需求方未来的变更。

有了这组对象,再想起来那些设计规范,进行细节的调整。

于是,我完成了软件的设计和开发,虽然不是最好的,但它能良好的运转,对我而言,我成功了。

关于界面

有一点需要注意,就在在模拟现实的时候,即对象设计的时候或者逻辑开发的时候,不要考虑什么界面的问题。

记住,界面附属于对象,并且服务于对象。或者你可以说,界面附属于程序,并服务于程序。

要做到界面与对象良好的分离,界面与逻辑良好的分离。

关于写代码

记住一点,永远不要陷到代码里面。

当设计完成后,就需要一点点的来编写程序实现设计,不要局限于某一个细节的实现而忽略了程序的整体把握。

当你遇到一个问题需要解决,我觉得首先要考虑的是我应该用什么方法来解决,如果这个方法受阻,就考虑另一个方法。例如要呈现一些数据,那么采用什么样的控件好呢??还是自己编写控件呢??

有三点需要注意,

第一,不要认准某个控件,非要用它不可,不行就换一个呗,要敢于尝试;

第二,不要使用平台依赖性太强的控件,也不要过度依赖第三方控件,如果控件帮你做了太多工作,你的程序就和控件捆绑太紧密了,这样不好;

第三,不要轻易自己编写控件,程序的BUG就够多了,别再自己给自己添乱了。

我觉得,面对问题,首先要尝试使用现有的技术去解决问题,当遍历了所有现有方法都无法解决,再考虑创新。

有时候,程序员在长时间编写项目某个部分时,会像一个孩子走入了森林,最后只见树木不见森林。

这就是程序员在代码中迷了路,程序员失去了对程序整体的把握。更糟糕的情况可能是,程序员开始砍树,即,由于思维局限在某一模块,程序员一时忘记了程序的整体设计,因为局部的问题去大改程序整体设计,这就太糟了。

为什么现在结对编程大肆提倡,并且评价很好?就是因为当一个人陷到代码里面,另一个人依旧保持清醒,可以把同伴拉出来。

记住,不要迷失在代码中。时常跳出你正在编写的模块,看看整体,思考一下。

C#是不是一个好的面向对象语言??VS是不是一个的OO开发工具??

C#是比java更彻底的面向对象编程语言,我看过一篇文章是这么分析的,而且在使用过后我也是这么认为的。在很多方面C#做的很优秀。

对此我没有太多的分析数据作为支持,故不多谈。

但对于VS,我的评价是:傻瓜式开发工具。

我认为C#是好的面向对象编程语言,但我坚决否认VS是一个好的面向对象程序开发工具。因为VS做的太智能了,太傻瓜式了,所以它也非常误导程序员,尤其是初学者和对面向对象掌握不牢固的程序员。

我想表达的是,VS试图让你进行基于事件的编程。这也是windows的运行机制。

看这样一个普通例子:

创建一个winform应用,拖拽一个面板,拖上去一个文本框,再拖上去一个按钮,双击按钮,好了,可以获取文本框内容并进行处理了。

哦??我们的确是在使用C#,一款面向对象的编程语言,但是,面向对象概念在哪里??对象在哪里??为什么我们的编程是从一堆控件的拖拽开始??为什么不是从一个类的设计开始????

VS把一些问题本末倒置了!!

第一,UI界面附属于对象,并服务于对象。或者说UI界面附属于程序,并服务于程序。而在VS里,我们的代码嵌在界面中,成为了界面的附属品!

第二,面向对象程序设计应该先进行类的设计,而VS中试图使人们组装控件并编写事件来实现软件。

记住,不要让工具控制了你,不要让VS控制了你。你应该征服VS,告诉VS说,去屎吧你,没有你我照样能开发程序。

如果面向对象程序设计在你的大脑内存中永久驻留,并且你拥有良好的编程风格(包括程序结构和代码风格),那么VS可以成为很好用的工具,毕竟控件的拖拽实在是太酷了,自动生成代码的功能太方便了,并且VS做这些工作时能保证BUG非常少。

在使用工具的时候,要时刻记住谁才是主人,要记住谁服务于谁。

也许一些简单的功能,需要耗费程序员大量的心血和时间。

虽然花了我一个月的日日夜夜开发,但软件看上去非常简单,只是一些窗体,面板,文本框,以及一些会变化颜色的按钮。按照需求方的需求,这款软件模拟了项目流程的运转,将原本需要人工管理的流程计算机化,以提高工程制作效率,方便领导管理。几乎是将需求方公司所有的工作管理计算机化。

做需求的时候,需求方说的很简单,他说,我希望这里有几个按钮和打字的地方,这样点一下,…,再在那里输入一下,…,最后这样点一下,就把一个项目的配置完成了。

他还说,我希望能自动产生与项目对应的一组按钮,我这样点点,…,那样点点,…,好了,这样就完成了一个项目的XX阶段的第一次交接流程。然后我再这样操作一下,就完成了第二次交接流程。

其实需求方说了很多,他说自己喜欢玩游戏,所以希望一切都是简单和方便的,界面是简单的,灵活的,操作是简单的。

并且神奇的是,他认为这样会令软件制作人员的工作变得简单……

是的,他是这么说的,他说这样操作很简单,你们做软件也会很简单。

我不知道他怎么得出的这个结论,但我也没法跟他解释说其实大部分看起来很简单的功能,都需要背后强大并且复杂的支持。

但要牢记,需求方的要求我们应该尽量去满足,而不是抱怨需求方的无知。可以协商,可以讨论,但决不能显露出无能。

于是,我制作了一些简洁的界面,并提供了简单的操作,并让一切用户可能用到的操作变得智能。这些“简单”,花费了我半年的时间。

技术?技术?

不得不承认,在很长一段时间里,我都轻视了我所从事的开发工作。

我是一个崇尚技术的程序员,一直以来技术都是我唯一的目标,掌握新的技术,使用新的技术是我做程序的目的。

初接触这个软件的需求,觉得做这样的开发并没有使用什么很牛的技术,也不会学习到很牛的开发技术,作为技术至上的我自然就轻视了这项开发工作,甚至带着不屑。

再加上我做项目的各方面经验不足,于是如上所述,我失败了。

我的导师后来说过两个观点,我总结如下:

第一,其实一个项目的成功,技术因素只占了不到30%的比例。项目成功是很多因素共同作用的结果,比如与现场良好的沟通以作需求,比如将需求转换为设计,并架构出良好的系统结构,再比如你如何忍受漫长并且枯燥的开发过程,比如你如何对待现场变幻莫测的需求……技术??技术只是在解决的上面问题后,将产品制作出来的手段罢了。

第二,对于技术要有正确的理解。其实项目从来都不是最新最高科技技术集合的产物,如果那样做你的项目只会难产。大部分时间,大部分代码,我们都在使用最普通的技术编写程序,只有在解决不了问题的时候,才会考虑去使用一些复杂的技术或者进行一些创新。

事实就是这样,计算机的世界是灵感迸发并且奇思妙想的,但产业化的项目开发过程更需要的是稳健,健壮。

结尾

昨天乔布斯去了天堂开苹果专卖店,听到这个消息后我翻了一下乔帮主的资料,偶然看到了乔布斯在斯坦福大学毕业典礼的演讲,非常受教。

乔布斯说,别失去信仰,我相信唯一让我坚持下去的原因,是我一直深爱我所从事的工作。你必须找到你所钟爱的东西,对于工作如此,对于你的爱人也是如此。

——努力寻找,不要停下。Keeping looking,don’t settle。

——几乎所有的事情--所有的期望,所有的荣耀,所有对失败的恐惧,在面对死亡时都显示微不足道。

纪念逝去的伟人,史蒂夫·乔布斯。

Stay hungry,stay foolish

-----------------------------------------------------------------------------

我要感谢的人,我的父亲,我的导师,还有野哥,小巫同学。

于2011-10-07夜
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: