软件工程之美

配套书籍:构建之法

[toc]

开篇

未来10年,什么不会变?

数据结构、算法、面向对象思想、设计模式、软件工程

基础理论

怎样理解软件工程

像这种有人参与、有计划、有步骤地造一件产品,我们通常称为“工程”。

就是要用工程化方法去规范软件开发,让项目可以按时完成、成本可控、质量有保证。

工程思维

软件工程不仅可以应用在软件项目中,还可以应用于日常生活中遇到的一些问题,Everything is a project

站在整体而非局部去看问题

工程思维,本质上是一种思考问题的方式,在解决日常遇到的问题时,尝试从一个项目的角度去看待问题、尝试用工程方法去解决问题、站在一个整体而不是局部的角度去看问题。

记录下两个孩子在MineCraft里面还原公寓的经历

瀑布模型

问题的定义与规划

需求分析

软件设计

程序编码

软件测试

运行维护

优缺点:阶段分的很清楚,但有点死板了。对于前期需求不明确的项目,很难开展需求分析,后续如果有需求变更,瀑布模型便很难响应

其它模型

快速原型模型

先迅速建造一个可以运行的软件原型,然后收集用户反馈,再反复修改确认,使开发出的软件能真正反映用户需求,这种开发模型就叫快速原型模型,也叫原型模型

增量模型

按模块分批次交付

迭代模型

每次迭代都是一个可用的版本

敏捷开发

敏捷不是一种方法论,也不是一种软件开发的具体方法,更不是一个框架或过程,而是一套价值观和原则

当你开发做决策的时候,遵守了敏捷开发的价值观和原则,不管你是不是用 Scrum 或者极限编程,那么都可以算是敏捷开发。

项目管理金三角

做产品想“多、快、好、省”都占着,是不可能的,最多只能选两样。

想要便宜和质量好,就要花时间等;想要快还要质量好,那就得多花钱;想要又便宜又快,那就得接受难用、质量差。

在软件项目中,有一个类似的平衡关系,就是软件质量(产品的质量,客户的满意度)与范围(需要实现多少功能)、时间(多久可以完成)、成本(花多少钱)四个要素之间的平衡。

项目规划篇

可行性分析

如何科学地论证项目的可行性,以及这个项目是不是值得做

可分为经济可行性、技术可行性、社会可行性

如果你想技术转管理,先来试试管好一个项目

代码未动,计划先行

如果没有计划,你的项目可能会陷入一种无序和混乱中。

参与做计划的过程,可以让你对项目的各种事情了然于胸,这就相当于扩大了你的上下文,让你有更高的视角看待当前工作遇到的问题。

如何制定计划?

第一步:任务分解;

意思是工作分解结构(Work Breakdown Structure, WBS)。就是把要做的事情,按照一个树形结构去组织,逐级分解,分割成小而具体的可交付结果,直到不能再拆分为止

第二步:估算时间;

主要还是得依靠以前的经验:

  • 任务拆分的越细致,想的越清楚,就能估算的越准确

  • 要让负责这个任务的人员参与估算

在沟通中也要注意技巧,不要采用质问的方式:“这么简单一个模块居然要 5 天?”这只会让听者产生逆反心理,无法有效的沟通。可以恰当的提一些问题来达到有效沟通的目的,比如我通常会问两个问题:

  • “能不能把你这个任务再细化一下?”
  • “能不能简单介绍一下这个模块你是打算如何实现的?”

对于估算的结果,通常还要考虑增加一些余量,因为实际项目执行过程中,并没办法保证是 100% 投入,有可能并行还有其他事情,或者一些突发事情、事先没有考虑到的任务都有可能影响进度。

第三步:排任务路径。

项目中有些任务是可以并行做的,而有些任务之间则是有依赖关系的。

排路径就是要根据任务之间的关系,资源的占用情况,排出合适的顺序。

制定计划时不要担心不够准确,先有一个基本的计划,可以粒度比较粗,不那么准确,让事情先推进起来。

设置里程碑

周期很长的项目,一直看不到结果,时间一长会很疲惫。所以有经验的项目经理会在项目启动后,根据制订好的初步计划,确定几个关键的里程碑

里程碑代表着一份承诺,在里程碑完成后,大家会获得一种正面激励。

在项目的推进过程中,根据里程碑完成的情况,你就可以很直观地知道项目的进展如何。如果发现不能如期完成里程碑,就需要进行适当的调整了

计划需要跟踪和调整

跟踪进度的方式主要有两种,一种是项目经理定期收集跟踪,一种是项目成员主动汇报。项目经理挨个收集的话,会有一个沟通确认的过程,对进度会了解的更准确;项目成员主动汇报,可以减少项目经理的收集工作,但有可能不准确。

流程和规范:红绿灯不是约束,而是用来提高效率

从个体来看,因为流程规范的存在,确实可能存在效率降低的情况,但从团队的角度来看,好的流程规范反而是提升效率的。

以代码审查的规范为例,对于技术高的程序员来说,代码审查可能会耽误一点时间,但对整个团队来讲:

  • 即使是水平高的程序员,也可能会被发现有错误,代码审查可以降低出错的概率,保障质量
  • 对于水平低的程序员,可以通过代码审查学习和成长,代码被高水平程序员审查后,可以有效提高质量。

如何制定好流程规范?

第一步:明确要解决的问题

要制定一个流程规范,第一步就是明确你是要解决什么样的问题。项目中很多问题,都可以思考是不是能通过流程解决。

第二步:提出解决方案

第三步:达成共识,推广执行

在流程规范提出后,还需要得到大家认可,只有大家认可,达成共识,才能共同遵守,保障制度的执行。

第四步: 持续优化,不断改进

流程制定后,在实际执行的时候,难免发现一些不合理或者不科学的地方,这时候就需要对其进行调整。

将流程规范工具化

尽可能借助技术手段来推动甚至替代流程规范。

白天开会,加班写代码的节奏怎么破?

如何提高开会效率?

我们先要认识到一个前提:那就是要让大家意识到开会是有成本的,如果开会创造的价值不能大于其成本,就是浪费。

  1. 砍掉一些没价值的会议
  2. 减少参与会议的人。会议的成本和两个因素相关:一个是人数,一个是时间。如果减少人数,就能减少成本。
  3. 缩短开会时间
  4. 提升会议所创造的价值

项目管理工具:一切管理问题,都应思考能否通过工具解决

基于 Ticket 的任务跟踪系统

那一个 Ticket 应该包含哪些主要信息呢?

  • 标题:摘要性的描述 Ticket 内容;
  • 类型:属于什么类型的 Ticket:Bug、需求、任务;
  • 内容:Ticket 的详细内容,例如,如果是 Bug 的话,除了要写清楚 Bug 内容,还需要重现步骤。如果是需求的话,要有需求的描述,可能还需要额外的文档链接辅助说明;
  • 创建人:谁创建的这条 Ticket;
  • 优先级:这个 Ticket 的优先级高还是低;
  • 状态:Ticket 的状态,例如:未开始、处理中、已解决、重新打开、关闭等;
  • 指派给谁:这个 Ticket 被指派给谁了,谁来负责;
  • 历史记录:整个 Ticket 改变的历史信息,用以跟踪;

风险管理:不能盲目乐观,凡事都应该有B计划

风险管理就是指在项目进行过程中,识别可能的风险,对风险进行评估,并加以监控,从而减少风险对项目的负面影响。

如何做好风险管理?

培养风险意识

项目中的任务,不能盲目乐观,都思考一下它最坏的结果是什么,如果最坏的结果不能接受,就说明要有个 B 计划,考虑风险管理了。

管理风险

第一步:风险识别,识别可能的风险

  • 项目风险:项目预算、进度、用户和需求等方面的问题;
  • 人员风险:人员离职、人手不足等问题;
  • 技术风险:采用的技术所可能带来的风险;
  • 商业风险:与市场、产品策略等有关的商业风险。

第二步:风险量化,对风险进行评估量化

第三步:应对计划,对风险制定应对策略

第四步:风险监控,对风险进行监控预警

怎样才能写好项目文档?

为什么要写文档?

写文档,其实对个人、对项目、对团队,都是非常重要的事情。

  • 帮助写文档的人理清楚思路.先写文档。先写文档,就会抛开代码细节,去站在全局思考

有人觉得自己写作不行,所以不会写文档。写作不行,只是让你在用词遣句上会有所欠缺,而这不是写文档的真正障碍

真正的障碍是没想清楚,在心中只有一些未成型的混乱的想法和概念,必须要努力把这些模糊的想法确定化和具体化,才能写出来。

换个角度来说,如果你连文档都写不出来,那又怎么能指望代码写得好呢?

  • 便于未来的维护和交接

我有一个习惯,每到一个新项目组,就会把日常工作中遇到的问题、各种环境配置、一些操作的步骤等,所有以后可能还会用上的都记录下来,其中一些还会整理到团队的 WIKI 上

  • 团队更好的协作沟通

如何写好文档?

很多人对于写文档是有心理压力,觉得自己写作水平不高,不知道该如何下手。首先你要对文档有一个正确的认识:文档写作,关键是通过文档把你的想法表达出来,至于用词、格式相对都是其次的。

  • 从模仿开始
  • 从小文档开始

项目中很多文档都可以从这样小的内容开始:别人给你讲一个问题的时候记录下来;你给别人讲一个问题的时候记录下来;解决一个技术难题时记录下来方案……

这些记录下来的笔记,稍加整理,就可以是很不错的项目文档。

  • 从粗到细,迭代更新

为什么我不一开始就写很细的文档呢?

一个原因是太难写,要花很多时间精力,甚至可能写不下去;另一个原因就是在收集反馈的过程中,会有很多修改。写得越细则无用功越多,最后,你甚至会因为不想改文档而抵触不同的意见。

基本的画图的技巧

写文档的时候,主要有几种图比较常用:线框图、流程图、时序图、各种格式的截图。

  • 线框图
  • 流程图
  • 时序图

在评审技术文档或者你自己写技术文档,你可以从几个角度去思考:

  1. 文档是否讲清楚了它的目的是什么?内容是否和目的匹配? 比如说你这个设计文档是要解决什么问题?设计的是哪个模块?

  2. 文档是否解释了为什么要这么做? 比如说你这个模块设计文档,是否解释清楚了为什么要这样设计?这样设计的优缺点是什么?

  3. 文档是否描述清楚了如何实现? 比如说作为模块设计文档,到底是如何设计的?有没有讲清楚整体的设计架构?

总结一下就是一个技术文档,要讲清楚:是什么(What)?为什么(Why)?怎么做(How)?这三个是最核心的要素。

这三个核心问题讲清楚了,然后就是多画图,内容简洁明了。

例子?

微服务:从设计到部署

需求分析篇

系统设计篇

架构设计:普通程序员也能实现复杂系统?

软件需求越来越多,而高手又是稀缺资源,所以要解决的一个问题就是:让普通程序员也能参与其中,一起实现复杂系统,而不必依赖于很多精英。

为什么软件项目需要架构设计?

复杂的软件项目,通常有两个特点:需求不确定和技术复杂。

什么是架构设计?

最开始我以为架构设计的目标是满足业务需求,保证软件能正常工作。后来发现这其实只是最基本的要求,因为很多糟糕的架构设计,也能满足业务需求,让系统正常运行。

架构设计的目标,是用最小的人力成本来满足需求的开发和响应需求的变化,用最小的运行成本来保障软件的运行。

架构设计,已经有很多成熟的方法:

  • 使用微服务这样的架构,把复杂系统拆分成一系列小的服务,服务再拆成功能模块,让人员更好地分工协作;
  • 通过前后端分离,让程序员更专注于某个知识领域,降低开发难度;
  • 用分层设计来隔离业务逻辑,减少需求变更带来的影响。

这些架构设计的方法,其实都是基于工程领域分而治之的策略,本质上就是将系统分拆,将人员分拆。但是光拆还不够,拆完了还得能拼回来

如何做好架构设计?

第一步:分析需求

架构设计,最基本的就是要能满足业务需求,所以搞清楚需求是至关重要一步。而产品需求,只有功能的描述,界面的交互,还需要进一步进行抽象。

一个常用的分析方法就是分析用例,也就是了解主要用户角色和其使用的场景。

第二步:选择相似的成熟的架构设计方案

软件架构入门

异地多活设计辣么难?其实是你想多了!

这篇文章有醍醐灌顶的感觉~ 解开了不少疑惑!

第三步:自顶向下层层细化

第四步:验证和优化架构设计方案

推荐材料