程序员

首页 » 常识 » 预防 » 程序员修炼之道第二版
TUhjnbcbe - 2020/9/24 14:57:00
北京中科白癫分医院 http://wapjbk.39.net/yiyuanzaixian/bjzkbdfyy/

时间过得好快,过年左右还在看云风在博客中说自己正在翻译这本书的第二版,然后现在就拿到并且已经看完,还带着少爷看了一点;这本书上次看还是在刚走出校门的时候,当时对这类以及软件工程书籍多少都看了一些,然而发现理解不了;最大的部头还是CodeComplete这样的巨著,修炼之道坦白讲,我已经忘记第一版说的了,所以,没有等Kindle版出现,买了实体的书拿来看。

其实说全忘记也不科学,这本书的英文标题叫做ThePragmaticProgrammer,以前在文章里面写过我内心对自己定位的方向第一个就是这个词,大概率跟这本书有关,也跟一个法国电影有关。三个词是:

Pragmatic

Sharp

ValueTrend

这次看第二版,我觉得以后还会经常翻出来看看,他大致属于心法那种,需要你有过体会有过共鸣才会aha的一本书;所以,刚走出校门就看,然后都忘记,应该是符合逻辑的,哈哈,其实应该经常翻出来看,计算机技术和工程毕竟是实践性非常强的一门手艺,加上发展又很快,所以,其实需要这样的心法不断校正自己的思维和习惯,形成务实的风格和体系。

这次读,在项目声明周期管理上对几个问题也算找到了一些答案,觉得还蛮有意义的,所以就记录下来,可能不仅仅是答案,也有共鸣,也有一些精神烙印的加强。从设计、到重构、到测试、到交付需求,最后究竟追求的是什么?所以,我们可以慢慢来讲讲,会比较长。

优秀的设计比糟糕的设计更容易变更。

这个是作者的14号提示,后面也提过几次,篇幅很短,力量却很重。ETC,——EasiertoChange,不是我们过高速的那个,是优秀设计的原则,甚至已经超越原则,是价值观念。项目最终面对的是他本身的复杂度跟程序员大脑容量之间的矛盾,加上每天都在变化的外部环境,ETC就是最终状态,甚至以前看过一篇文章写,尤其如果你是做业务系统的,你的代码应该Easytodelete,该删就删。所以,在第二章中,作者讲了很多从这个价值观发展下来的原则,例如DRY、SRP等;其实,感觉这里没有什么好说的,就应该是这样的,最后体系结构的发展什么的,都是离不开这个原则,比如我们做分层,为什么分层,就是职责分离,为什么职责分离,在后面的发布部署扩容都是ETC的,所以,觉得没什么好说的。不过总要放在这里,表示这个是本书中最重要的一句话!

问题1:重构的目的是什么?以及一个大问题,是作者在书中跟着重构的这个部分发表的一个观点——系统究竟是像建筑那样,使用模式规划出来,还是类似一个有机体,自己“长”起来的?我记得以前好像有个Google的架构师还写文章说过这个问题。

随着程序的演化,其实需要程序员不断的停下来去还技术债;我觉得大部分技术人员或者技术管理人员一个苦恼的来源是,没有办法在项目进展过程中插入自己的checkpoint,没有办法叫停PM或者老板在新项目上的投入和进度安排,眼看着自己的代码变成一团乱码,自己心里越来越焦虑,最后离开团队,然后来了新人,压根不想接,索性,跟PM或者老板讲,上任太差了,我接不了,我必须从头做,于是第二个循环开始了~谁能打开这个loop呢,我自己会去平衡项目的进度和技术债的堆积,必须要重构;必须要review,做完每个里程碑,都要review,如果当初为了让功能work已经欠很多债,那就必须要切换到“扫房子”的工作上去。这就是重构的意义。——不要开启这个恶性循环。

好像是n年前毕业的时候,设计模式开始流行,然后弄得一个建筑师写建筑模式的书也很火,从那个时候开始,我们就被打上了一个精神烙印——我们程序员跟建筑师的思维方式是可以一样的;因为在当时,软件开发最常见的隐喻就是建筑的构建。商务人士或者职业经理人也觉得这个隐喻太高大上了,并且工程可重复,管理上有严格的汇报层次关系,于是这个系统就围绕着这个隐喻教育了我们很多年;到现在我都觉得从那个时代过来的程序员还保留着对模块化可插拔、高重用高复用这样美好世界的YY,然鹅每次都是一次巨大的挑战,也许就跳下了深渊。作者在书里面倾向于把软件工程或者架构设计类比为园艺,他需要你不断的修剪,不断的松土,不断的更换某个区域的布景等;我自己一直都觉得他像是个有机体,终究有部分会死去,那需要砍掉,也有部分在不断的在发展增强;所以,作者也说,尽早重构,经常重构。

问题2:怎么做测试?这个其实是困扰我挺久的问题了,上上个工作,我们核心研发才10个人左右的时候,老板把我们叫到办公室开会,说只讨论一个问题——“我们需要设测试的岗位吗?”,所有人都说不需要,于是就定下了后续在那个部门长达很久的没有测试岗位的惯例。上个工作,我提过几次,我觉得几乎不会有人答应,我就很怀疑当初我们是怎么那么快的做出决定的呢?

从沟通层次和管理层次上来看,虽然整个部门都没有测试团队,但不会意味着我们不去做测试工作,当然我也不能说我们当时的单元测试就特别全,或者覆盖率就特别高,但是因为缺少守门员,所以每一个开发同学就会更慎重,不能随便扔锅给别人了;lead会多少承担一些集成测试和压力测试的工作,因为workload比较大,所以,这些lead上来就会考虑自动化测试的事情,先驱者(项目开启的人)大概率也会提供mockserver的功能,因为他们自己上来就需要。产品上线之前,我们会召集所有PM、运营同学做bugbash,大家其乐融融互相杠……

如果有测试部门,我以前的经历中面对的问题是,开发同学自测的很少;测试同学压力很大;ticket的流程中转很多,尤其是开发和测试同学不在一个楼层,基本我们只盯着ticket的状态,天天刷列表;测试同学其实也不太了解业务逻辑,所以,还是会有很多的沟通工作;出事之后,真的谁来承担责任,这个算是千古难题吧,因为太取决于老板的性格了~团队之间,我觉得要么就互相吐槽,要么就互相取暖;虽然说共同承担责任,但是挺理想化的,不太务实~

嗯,我没有什么结论,我们现在团队也小,所以,3年内应该不会有测试岗位,但是不代表不做测试工作,也不代表就推荐给大家的团队,但是感兴趣的话,可以搜搜国外公司对QA职位的思想变化,但关键的一点,程序员不要把自己从测试工作中剥离出去。

坦白讲,工作20年了,我的第一份工作就是QA,到现在我还不愿意写测试用例,虽然n年前我也研究过TDD,也跟室友炫耀过写case的数量,但是有时候在想TDD是否真的合适,会不会overdo,你究竟要测试的是什么,尤其是我们做CRUD,上来写case判断入库出库,那你是在测试自己的代码,还是在测试人家ORM的框架呢?还好作者基本消除了我的疑虑:

测试与找Bug无关。

哈哈,标题*啊,不过很认可作者后续的逻辑了。“测试获得的主要好处发生在你考虑测试以及编写测试的时候,而不是在运行测试的时候。”所以,“测试是代码的第一个用户。”醍醐灌顶有没有,其实实际上可能自己是这么做,比如做webserver,我大概率先会写URL会怎么安排、参数怎么传递,这些请求体先写好,然后才去写handler,不过总觉得人家作者总结的更好,也基本为我不去追求覆盖率和case数量提供了很好的借口,哈哈哈。不带着大家回顾TDD的大致过程了,虽然最后你的测试代码数量远远超过业务代码数量,然后case全绿色pass给你特别大的安全感,但是这里关键的问题不是TDD,也不是全pass,而是case;我以前总在想,我们怎么衡量一个case写的好不好呢,他究竟是randomcasepassed,还是logiccasepassed,不觉得这是个难题吗?所以,不管使用什么方法、流程和指标,最底层的问题是你的目标是什么,你有没有在解决问题,是不是工作在Value的80%解空间域上?

这里有一个很大的延伸问题?构建系统“自上而下做,还是自下而上做”?你可能会问,我擦,这算什么问题?我们还拿比较常见的CRUD来举例,自下而上通常就是我们先做实体存储,然后做实体的API,然后做实体对应的缓存结果,然后提供实体基本的resetfulapis,然后再看最后需求端比如是个app他需要什么样的接口进行组装;自上而下可能就是,我们先看App那边的接口,然后大概率提供的是rpc类似的api,比如payAndOrder,然后再组装实体、存储啊缓存啊等等。自下而上是先提供小功能模块,然后逐渐组装;自上而下通常是逐渐拆解大问题,形成小问题,然后再解决小问题。

作者提供了一个68号提示:既非自上而下,也非自下而上,基于端到端构建。这个也暗合作者对于测试用例的看法,他也建议case大多都是端到端构建出来的case。作者相信,构建软件的唯一方式是增量式的。构建端到端的功能模块,不断学习和了解构建过程中的领域知识;因为作者觉得不管用什么方向是构建,前提可能都有一点不满足,就是我们并不知道我们的需求是什么?所以有了下面这个问题。

问题3:需求从何而来?开始看到作者写这个问题,甚至写下类似“程序员帮助人们理解他们想要什么”这样的话时,不禁在想,老外没有PM吗?需求有一个神话,就是他会在一定时间内已知的、不变的。然鹅事实从来不是这样,国内伟大的PM越来越多,开发人员能够接触实际需求的机会其实是非常少的,我觉得在大部分国内的PM和程序员之间也基本有了这种分工的默契;记得以前开会的时候,碰到一些跟产品发展有关的问题,我们程序员是需要离场的~很郁闷,我觉得大家都是在这个商业模式链条上的Stakeholder,关键利益者,在老外的很多书里面都会提到这个词。于是需求在开发者看来就更是一件神话的事情。

我觉得也没有什么好多说的,两点,作者也都提了:需求是一个过程;和用户一起工作。我觉得怎么强调都不过分吧。此外,从端到端的设计和构建这个角度来讲,UserStory是特别好的需求整理方式,他就是对端到端的描述,但是我们现在大概率首先接触到的都是设计稿,然后一个设计稿上n个交互点,哪种方式更好,估计每个公司都不一样——设计稿其实也是一种端到端的需求描述,但是被聚合在一起了,在任务和里程碑的拆解上,不算合适的。个人观点,毕竟隔行如隔山~

问题4:这些东西要解决的终极问题是什么?修炼的是什么?其实我最近还在同时看一本Devops的书,那本书前5章都在讲道,我觉得跟这本书的最终思想是一致的。所以,除了作者提到的敏捷,我又加了个精益。

学习这么多终极目标是什么?

把软件产品交付给用户!

什么是务实的做法?

敏捷、精益!

什么是精益?

小批量任务交付是提升质量、客户满意度和员工幸福感的关键因素,这就是精益!

什么是敏捷?

快速响应用户的需求变化,更新对用户领域知识的理解到系统中,做出容易改变的系统产品,及时交付给用户,这就是敏捷!

我按照我自己理解写的,虽然已经好多年不太去接触敏捷和精益这样的词了,不过一直很认可精益,我们也不断的在使用小里程碑的方式去做,绝对不赞赏“憋大招”,最后把自己憋坏了;不过今天读完,对敏捷又清楚了一层,以前还是有些困惑的,包括很多高级理念、流程、SOP、Scrum、站会,我都不太理解。技术永远都是手段,他是来解决问题的,那这些手段在解决什么问题?作者在这里也没有说太多,他说其实关键问题已经在敏捷宣言里面的价值观写的很清楚了。

敏捷宣言四条价值观:

个体和互动高于流程和工具

工作的软件高于详尽的文档

客户合作高于合同谈判

响应变化高于遵循计划

第一条尤为重要,团队要敏捷必然来自于一个充分沟通无障碍的团队,来自于实施团队跟用户之间的互动合作,我觉得是基础,所以,最近一个月我们都没有再更新sprint了,本来稍有些焦虑,后来发现,我们现在过程中的个体的互动沟通特别充分,那其实何必执拗于工具呢?

敏捷永远不是一个工艺流程,更不会是一个标准流程模型;他是一种选择,一个形容词;底层逻辑来源于系统动力学中的增强反馈,敏捷都在说要加强反馈过程;而最后结果是要为用户交付可工作的软件。

随着人的成长,软件的复杂度不仅仅来自于代码级别,越来越多会来自于项目级别,来自于沟通级别,但是为了更好的解决这些复杂度的产生,回避他们不会是出路,只有去迎接挑战。而伟大的项目管理者,都是复杂度的“高级驯兽师”,掌握的信息、广度和深度,自身和团队的思考、沉淀,鼓励改变、拥抱变化,迎接挑战,像每一个工匠一样,自豪的为自己的作品签上名字,传递给后人~

所以,作为一个四十岁的工程师,我们并不需要担心太多,嘿哈!

预览时标签不可点
1
查看完整版本: 程序员修炼之道第二版