0%

工程开发经验总结二,如果我是甲方,该如何外包?

本来是想直接写下的,半路除了点问题,写一篇中吧。具体出了什么意外呢?当然是自己不太熟悉的 git 操作,实在是缺乏和别人一起开发项目的经验。后来又陆续有一些其他的收获,一并整理。

承接上文,在代码开发与测试完成后,其实工作量才完成了一半,对的,你没听错。

关于代码提交

提交代码自然而然用的是 git,但是甲方的代码开放程度是不同的,甲方的主代码我们称为 master 分支,每个组有一个 ownerowner 能直接获取 master 的仓库,而开发人员只能获取 owner 的仓库。

这种操作就导致了一个问题,代码更新不及时,开发者和甲方沟通低效。开发者想要更新仓库,就必须先让 owner 更新;甲方提出代码的问题,就必须由 master 转发。

暂且假设更新成功,本地提交时,创建分支,提交代码,由于没获取 master 仓库的权限,只能由 owner 发起 pull request。而众所周知:一件事情经过的转手次数越多,经过的人员越多,处理速度就越慢。脑补你办一件事情,一张纸要盖很多章,那些人踢皮球的水平超乎你的想象。

其实这也不能怪 owner,如果这是在公司,上班时间我们开发的会很快;但是这是在学校,且还是研究生,你永远不知道你的老师会在什么时间给你安排什么奇奇怪怪的任务,事情一多就容易耽误,且心累。

再次假设,pull request 成功了,由于 master 频繁收录提交的代码进行更新,刚刚提交的 pull request 很可能代码冲突,此时就需要手动处理。我尝试了用 gitee 的界面进行处理,结果,呵呵,我们组全部的 pr 被我弄没了,全部重新提交,大型操作失误现场。

之后尝试用命令行操作,手动处理冲突并提交,pr 处显示没冲突,但是代码审核就是有冲突,冲突的位置我看了一下,本地明明已经处理好了。也许是我 git 操作不熟练,也许是线上环境的问题,很奇怪,最后也没有修复,重新拉取最新,草草提交了。

这前前后后大概浪费了三天宝贵的时间,这也在提醒我,抽时间学 git

关于修改程序

因为需求性分析搞错了方向,导致我在这上面吃了大亏。当时大概有两种可行路线,一种是 A 路线,一种是 B 路线,两者只是表现形式不一样,但最终结果是一样的。我当时盲目自信,以为都行,就选择了 A 路线。后来个甲方沟通才知道,要实现 B 路线。这就导致了代码大改,白白的浪费时间和精力。 以至于为了赶进度,我还叫别人帮我一起改,可真是愧疚。

实现代码的改动会带动原型定义代码、测试代码的一起变动,难确实不难,恶心是真的恶心。我也第一次体会到,实际开发中,测试代码会比实现代码多的多。而且改代码的时候需要注意,改一点编译一点,不要一次性改一堆然后一次性编译,出错了都不知道是哪错了。

用一句话总结吧,中国有个成语叫管中窥豹,但也有见微知著,有一叶知秋,也有一叶障目不见泰山,无论如何都有个成语,叫自以为是。

从甲方的视角看代开发

因为在开发的过程中遇到了一些困难,不是实现代码的困难,而是理解逻辑的困难。所以引出了这个思考,如果我是甲方,我把项目外放给别人,我应该怎么描述问题,才能让对面完成的更好?毕竟花同样一份钱,我希望拿到更好的程序。

第一点是提前告知项目的所有内容。这次开发有两个任务,第一个任务是开发和测试,第二个任务是适配。当时大家都以为适配很简单,外什么呢?因为一开始根本看不到第二个任务的说明书和文档,只有做完第一个任务才能看到后续任务的文档。相比之下,我们都认为适配会比开发简单的多,所以时间花费不合理,导致在开发浪费的过多的精力。等看到第二个任务的文档时,才发现代码量不会比开发低,但此时已经没有时间了,只能延期。如果是我,我会提前告知,以及在开发期间进行适当的催促。

第二点是整理常用的编译命令。因为大型项目的编译不是点按钮就能实现了,需要在命令行执行很长的了命令。我会写单独的一个文档,把这些命令从文档的各个角落收集起来,方便开发人员的粘贴。不然翻来翻去太麻烦了,真的。

最后一点,也是我认为最重要的一点。在文档之中,而不是文档之前进行一个逻辑说明,而不是单纯的告诉用户哪个文件的程序该怎么写。为什么呢?配置环境,如何开发等基础文档在这里就先忽略了,不是重点。

如果把概念性的东西写在最前面,开发者读起来会晕,而且不知所云。放在文档中间,当用户写完程序后,相对有了一定了解,知道代码写的是什么,在看到概念性的东西会比较直观。这就像看当代论文一样,先看摘要和引言,丝毫不知道在说什么,往往看到最后才明白。这其实和中国人的思维不符。举个例子,中国人盖房先打地基,自底向上,外国人盖房先设计房顶,自顶向下。两者都没有错,可中国人习惯了自底向上,被迫看自顶向下的东西不舒服。再举个例子,学计算机网络,是从物理层学到网络层,还是从网络层学到物理层?

其次,我要告诉用户他写的那些文件之间是什么逻辑。假设有 A B C 三个代码,开发者可能以为 A 会调用 B,为保证运行正确,B 中需要进行初始化操作;但其实呢,A 不会调用 B,B 也不用初始化,因为初始化工作已经在 C 中完成了。相信我,当项目规模十分庞大的时候,复杂的文件以及这些调用关系不是人眼能看出来的。即使能看出来,你也不会相信这种调用关系,不信?我举个例子。A 是测试代码,里面含有正确结果,B 是实现代码,B 需要把返回结果写到数组中,但数组大小未知。

  • 第一种情况,B 不需要经过运算获得数组大小,直接把结果写到测试代码的结果里面就好。
  • 第二种情况,B 需要运算并获取数组大小,开辟新的数组,将结果写到新的数组,并返回与测试结果对比。

正确答案是第一种情况。为什么不用具体实现?实际调用代码的时候没人会给你测试代码提供结果啊?代码不实现功能怎么能行?刚开始我也这么想的,但后来发现在实际使用的时候,会在一个默默无闻的 C 文件的代码中对 B 文件中的代码进行初始化,这就是没有搞清楚逻辑的后果,再次导致了代码的改动,而这种改动是可以在一开始避免的。

那么对于乙方,如何避免这种情况呢?开发的时候多和身边的人聊一聊,要多问多交流,而不是闷头凭自己的感觉和想象写程序,独行快,众行远。

感谢上学期间打赏我的朋友们。赛博乞讨:我,秦始皇,打钱。

欢迎订阅我的文章