《代码大全》是本经典著做,不一样阶段,不一样水平的人看了必然会有不一样的感觉。像我这种新手最关注的多是代码质量部分,而高手可能会更加关注架构。本系列博客是本身在学习时的一些记录和感想,偏前端,或许不少内容你都了解了,但你必定会发现亮点。html
软件开发过程当中包含了许多不一样活动,一套专业完整的流程是这样滴:前端
定义问题程序员
需求分析编程
规划架构segmentfault
软件架构或高层设计安全
详细设计架构
编码与调试框架
单元测试与集成测试编程语言
系统集成和测试函数
保障维护
这是传统的软件开发模型,许多高校的毕业设计就是按这个模型来的。当时最大的感受就是文档写的飞起,写代码反而意犹未尽。事实上,这才是真正意义上的“编程”(除去定义问题以外的其余全部活动),写文档的过程其实包含了规划和设计的工做,当详细设计的工做完成后其实程序逻辑已经很是清晰了,这时候”编码”就成了一种机械化的体力活。
而软件构建,就是以编码与调试为核心的编程,俗曰编程。
编程(programming)和编码(coding)的区别就比如工程师和码农的区别。前端在接需求作开发时不少活动是在脑子里完成的,这样减小了时间和文档设计成本,可是增长了编码和维护成本。
前端编码的工程化如今发展的愈来愈完善了,可是软件构建的工程化貌似还不太成熟(或许跟公司和部门以及业务有关),一些部门在开发项目时大概活动是这样滴:
定义问题(产品经理提需求啦)
需求分析(你们快来开会,咱们来讨论下这个需求)
规划架构(这部分变成了排期,需求定好了,视觉,前端,后台,测试,大家排下期...)
软件架构或高层设计(本身边设计边写代码去...)
详细设计(本身边设计边写代码去...)
编码与调试(写得飞起)
单元测试与集成测试(自测经过没?经过能够提测了)
系统集成和测试(测试一边测试一边提bug,改完bug就能上线了)
保障维护(啥?体验很差?线上故障?赶忙保障保障...)
可见在商业公司的软件构建流程中,最重要的软件设计部分并无和实际编码分开进行,而是很”敏捷”的融合在一块儿了,这种方式各有利弊,在于取舍。
提升软件的质量和开发者的生产率很是重要——这是全部码农的共识。
而软件构建的质量直接影响软件的质量和生产效率:
构建活动是软件开发的主要组成部分。构建活动在整个项目开发期中占据了30%~80%的时间;
构建活动是软件开发中得核心活动。
提升程序员的生产率。在构建活动期间,不一样程序员的生产率差率可达10~20倍。是否是好奇为何你老是很忙么?好奇为何大神的开发效率老是那么高么?后面会讲到。
构建活动的产物——源代码,是对软件的惟一精确描述。文档只是参考,代码才是硬道理。
构建活动是惟一一项确保会完成的工做。
现实状况下软件项目每每跳过需求和设计直接进入构建环节,以后又因为bug太多致使时间不够,测试环节也不那么严谨。可是不管项目有多匆忙,构建活动都是不可或缺的,对构建活动进行改进,是改进软件开发过程的有效途径。
使用隐喻能够更好的理解编程,也能很形象的向别人解释一些晦涩的技术。
隐喻这个装逼的词汇其实就是一种比喻,好比计算机世界里面所说的病毒(virus)、蠕虫(worm)、臭虫(bug)等等,都是隐喻。隐喻描述了软件领域中各类特定现象和事物,借助这些隐喻,咱们可以更深入的理解软件开发的过程。
重要的研发成果每每来自类比,经过把你不理解的东西和一些你比较理解又很相似的东西做比较,你能够对这些不理解的东西产生更深入的理解。这种使用隐喻的方法也叫建模。
就好比气体的分子运动理论是基于”撞球“模型,它把气体分子想象成有质量且彼此发生弹性碰撞的小球,有不少有用的理论就是基于这个提出来的。
又好比光的波动理论是经过类比声波发展起来的。并提出了”以太“的概念,但很不幸的是,此次经过类比声波来建模的研究失败了,由于并无找到”以太“这种东西。
从托勒密的地心说到哥白尼的日心说,花了1400年。而在这一千多年间,人民坚信不移的认为地心说模型是对的,当一个更加合理的日心说模型出来时,全部人都以为这是错的。当人们相信新的理论时,都会以为旧理论很荒谬;而当人们还在相信旧理论时,一样会认为新理论很荒谬。科学的发展史并非一系列从”错误“的隐喻到”正确“的隐喻的转变,而是一系列”不太合适“的隐喻到”更好“的隐喻的转变。
相对于其余学科而言,软件开发还很年轻,尚未一套成熟标准的隐喻。所以必然存在许多互补或互斥的隐喻。你对隐喻有多理解,也就决定了你对软件开发有多理解。不一样的隐喻彼此不必定排斥,应当使用对你最有益的。
我想起了一篇译文章进程与线程的一个简单解释,若是你以为文章隐喻的很是巧妙,那说明你并未深刻理解进程和线程的关系。
隐喻是一种启发式的方法,那么该如何使用它呢?
经过它来提升你对编程问题和编程过程的洞察力
帮助你思考编程过程当中得活动,想出更好的解法
相对于不善用隐喻的人,那些使用隐喻来照亮本身软件开发过程的人,他们对于编程的理解会更好,而且可以更快的写出好代码。
项目的成败很大程度上在构建活动开始以前就已经注定了,若是地基没打好,或者计划不充分,那么你在构建期间能作的无非是尽可能让损害最小罢了。
准备工做的核心目标是下降风险,要根据不一样项目特色来选择不一样的下降风险的方法。准备工做不足致使的直接后果就是项目延期,项目质量低,线上风险大,上线以后又频繁改需求。
大部分程序员都明白前期准备的重要性,可是大部分程序员都没法抵抗”尽快开始编码“的欲望。除了程序员,管理层也是这样。有个很装逼的词汇叫作WISCA综合症(Why Isn't Sam Coding Anything?为何Sam不在写代码?),或者WIMP综合症(Why Isn't Mary Programing?为何Mary不在编程?),介于这两个因素,实际项目开发时每每是准备不够充分。
在某部门,他们作一个项目的大部分时间都花在了会议和撕逼上,也就是花在了软件设计上;而在某某部门,项目时间大多花在编码和测试上。到底哪一种模式好?须要数据来论证,也跟项目类型密切相关。可是单从质量上来看,确定是前者更优。
两种模式都关注开发质量,可是一个在项目初期,一个在中/末期。若是你想开发高质量的软件,软件开发过程必须自始至终关注质量,在项目初期关注质量,对产品质量的正面影响比在项目末期关注质量的影响更大。
程序员的一部分工做就是教育老板和合做者,告诉他们软件开发过程作好准备工做的重要性。
不一样类型的项目,须要在”准备工做”和“构建活动”之间找到平衡。目前经常使用的开发方式有序列式和迭代式,前者适用于需求稳定,技术熟练,风险小得项目,后者适用于设计负载,需求并未理解透彻,项目包含了诸多风险等项目。
商业软件开发中经常使用迭代式。
问题定义在需求分析以前,需求分析是对问题的深刻描述。若是没有一个良好的问题定义,你努力解决的多是一个错误的问题。
要有一套明确的需求,这很重要。理由不少:
明确需求有助于确保是用户(或产品经理)来驾驭系统的功能。不然程序员就会经常在编程期间自行决定需求。
明确需求有利于避免争论。
重视需求有助于减小开始编程开发以后的系统变动状况。若是在编程过程当中发现一个代码上得错误,你可能只须要改几行代码,可是若是发现一个需求错误或变动,哈哈。
稳定的需求是软件开发的圣杯。一旦需求稳定,项目就能有序平稳的进行。但实际上,IBM和其余公司研究发现,平均水平的项目在开发过程当中,需求会有25%的变化。因此在构建期间,咱们不得不该对这种变动:
创建一套变动控制程序。这个成熟的公司都会有的,好比阿里的aone。
使用能适应变化的开发方法,也就是选择合适的开发模型。
注意项目的商业案例。好比有时视觉作了个很酷炫的功能,但这个功能是否是用户真的须要的?是否能提升转化率?仍是视觉只是想突破自我?有些需求做为功能特点来看是不错的想法,可是当你评估”这个需求到底增长了多大的商业价值“时就会以为它糟透了。那些记得“考虑本身的决定所带来的商业影响”的程序员的身价堪比黄金。
确保每个人都知道需求变动的代价。这是程序员的工做之一,不少产品经理/运营或其余需求方根本不懂技术,他们认为很小的一个改动,应该一两个小时就能解决的。但有时候最麻烦的多是那些懂一点点技术的需求方,他们可能接触过,或者写过一点demo,因此天然而然认为这很简单。你最好让他们知道实际成本,不然坑的是本身。
使用需求核对表来评估你得需求质量。
若是连你本身也不知道这需求是否合理,要作多久,你能够列个表格来核对一下。这样能帮你本身理清思路:
1.是否详细定义了系统的所有输入/输出,包括来源、精度、取值范围?
2.是否详细定义了软件/硬件的外部接口?
3.是否列出了用户想要作的所有事情?
4.是否认义了每一个任务所用到得数据?
1.是否为所有必要的操做?
2.是否描述了指望响应时间,处理时间,吞吐量等指标?
3.是否详细定义了安全级别?
4.是否认义了可靠性?错误检测和恢复策略?
1.需求是用用户的语言书写的马?
2.需求之间是否冲突?
3.需求是否足够清晰?
4.需求是否均可测试?
5.是否描述了全部可能对需求的改动,包括各项改动的可能性?
1.对于开发前没法得到的信息,是否详细描述?
2.你对所有需求都感到舒服吗?你是否已经去掉了那些不可能实现的需求?或者说并无什么卵用的需求?
上面这个表格只是列出了一些点,不一样项目的核对点确定不一样,可是能够参考,帮助你本身理清需求思路很是重要,当需求来临以后,咱们不仅是考虑到何时可以上,还应考虑上述因素以及所以而带来的成本。
天啦撸,看到这里已经感同身受了。
架构的质量决定了系统的最终质量。离开了良好的软件架构,你可能瞄准了正确的问题,却使用了错误的解决方案。
在前端,架构的选择好像就是框架的选择,构建工具的选择。可是抛开任何框架,或者本身要从头开始搭建,你须要考虑下面问题:
这上面的每个点水都很深,就拿错误处理来讲,你的设计应该考虑到:
错误处理是进行纠正仍是进行检测?
错误检测是主动仍是被动?
程序如何传播错误?
错误消息的处理有什么约定?
如何处理异常?
在程序中,在什么层次上处理异常?是在发现错误的时候处理?仍是传递错误到统一的地方处理?仍是沿函数调用链向上传递?
每一个类在验证其输入数据的有效性方面须要负什么责任?
你是但愿在运行环境内处理错误,仍是创建一套本身的机制?
天啦撸,架构师真不容易。
最后,架构不该该包含任何仅仅为了取悦老板的东西。
任何一种GPL都有跨界的能力,若是你爱折腾,你能够用Python,用Haskell来写前端,但这并非一个好主意。任什么时候候,都不能为了使用某种语言而选择它。
编程实现必须与指导该实现的架构保持一致,团队必须使用同一套编码规范,这点却是比较容易作到,尤为是在大公司。
在技术浪潮前期,针对新兴技术的编程语言和框架都比较少,程序员花费了大量时间,都是为了弄清语言是如何工做的,而非编写新的代码。程序员还花了大量时间来绕过语言产品的bug、下层OS的bug以及其余工具的bug。
在技术浪潮末尾,咱们有大量的编程语言和框架可选,拥有完善的错误检查和调试工具以及自动化优化工具,以及各类学习资源和训练课程。
举个栗子,VR的开发如今正处在浪潮前期,而前端开发则处在浪潮之巅。
理解本身在浪潮中的位置,有助于本身更好的面对编程工做。若是在前期,你可能须要花大部分时间来”造轮子“或”修轮子”,若是在后期,你只须要关注编写新功能。
“在一种语言上编程(programming in a language)”的程序员将他们的思想限制于”语言直接支持的那些构件”,若是语言工具是初级的,那么程序员的思想也是初级的。
“深刻一种语言去编程(programming into a language)”的程序员首先决定他要表达的思想是什么,而后决定如何使用特定语言提供的工具来表达这些思想。
构建实践方法有不少,从编码,团队协做,质量保证,开发工具各个方面有意识的选择最适合你的项目的实践方法。
以上,是在编程以前的工做。
编程前的工做看着有些无聊,但却很是重要。以后会继续分享本身的一些心得:
能够很明显的看出对于架构部分我基本是略过.....额,不过有趣的是,等再过两三年本身水平提升了一个档次以后,再回来看架构部分必然会有更深入的体会,如此也是记录本身成长的一部分,善哉。