软件工程之美

简介:   最近在阅读《软件工程之美》,特在此做点记录。

一、项目规划


1)平衡软件质量与时间成本

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

  • 老板要压缩项目时间怎么办?老板希望时间是 1 个月,也就是说时间这条边被缩短了,那么结果就是会影响到另两条边:范围和成本,如果另外两条边可以调整,也不是不可以。
  • 产品经理要临时加需求怎么办?增加需求,也就是范围这条边要增加,那就必然对成本和时间这两条边造成影响,要么延期,要么增加成本。

  从时间、成本和范围这三条边中找出来固定的一条或者两条边,再去调整另一条边。

2)可行性分析

  对于软件项目的可行性研究,主要从以下几个方面入手:

  • 经济可行性:从成本和收益角度分析,看投入产出比。不仅要分析短期利益,还要分析长期利益,看是不是值得做。
  • 技术可行性:软件项目最终是需要人通过技术来实现的,所以要分析技术上是不是可行,如果有技术上解决不了的问题又能否规避。
  • 社会可行性:社会可行性涉及法律、道德、社会影响等社会因素。比如,触犯国家法律的事情肯定不能做;产品如若不符合道德标准,可能带来较大的社会负面影响,那么也要慎重考虑。

3)项目计划

  制定项目计划,通常有三个基本步骤:

  • 第一步:任务分解,把复杂的问题拆分成简单的问题,大的模块拆成小的模块,在工程里面这个叫“分而治之”。分割成小而具体的可交付结果,直到不能再拆分为止。
  • 第二步:估算时间,有很多方法可以参考,主要还是得依靠以前的经验。要想估算准确需要从两个方面入手:任务拆分的越细致,想的越清楚,就能估算的越准确。要让负责这个任务的人员参与估算。
  • 第三步:排任务路径,根据任务之间的关系,资源的占用情况,排出合适的顺序。

  有经验的项目经理会在项目启动后,根据制订好的初步计划,确定几个关键的里程碑。

  项目管理中,并不是计划制定好了就完事了,还需要跟踪和调整。跟踪进度的方式主要有两种,一种是项目经理定期收集跟踪,一种是项目成员主动汇报。

4)流程和规范

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

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

  借助流程规范,让项目管理从人治到“法治”。

  好的项目管理,不需要直接管人管事,而是管理好计划和流程规范;项目成员不需要按照项目经理的指令做事,而是遵循计划和流程规范。

  制定流程规范的四个步骤:

  • 第一步:明确要解决的问题,例如:数据库操作之前先备份数据库,事先写好 SQL 语句,需要有人审查,测试环境先测试通过,最后再生产环境执行,那么就可以避免以后再出现不小心删除数据表的事情发生。
  • 第二步:提出解决方案,先思考解决的方法,有了方法后再进一步思考是否能提炼流程规范。
  • 第三步:达成共识,推广执行。对于大家都认可、很重要的流程规范,一定要让大家严格遵守,必要的时候需要配合一些奖惩制度,以保障其执行。
  • 第四步: 持续优化,不断改进。随着时间推移,可能已经不能符合要求了,也需要考虑改进甚至放弃,不然反而会成为一种阻碍。

5)白天开会,加班写代码

  开会其实是有成本的,而且还不低。需要减少开会的成本:

  • 砍掉一些没价值的会议。
  • 减少参与会议的人。
  • 缩短开会时间。
  • 提升会议所创造的价值。

6)风险管理

  风险是指不确定的事件,一旦发生,将会造成消极的影响。风险包含两个方面的内容:

  • 发生后,会造成什么样的损失?
  • 发生的概率有多大?

  风险 = 损失 x 发生概率。

  对软件项目风险的管理,才是体现项目管理水平的地方。我们对比下面几种应对风险的层次来看:

  • 被动应对:风险已经发生,造成了问题才被动应对;
  • 有备无患:事先制定好风险发生后的补救方案,但没有任何防范措施;
  • 防患未然:对可能的风险做出防范,并把风险防范作为项目任务的一部分。

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

  软件项目风险管理,通常分四步来做。

  • 第一步:风险识别,识别可能的风险。软件项目的风险主要分成以下几类:
  • 项目风险:项目预算、进度、用户和需求等方面的问题;
  • 人员风险:人员离职、人手不足等问题;
  • 技术风险:采用的技术所可能带来的风险;
  • 商业风险:与市场、产品策略等有关的商业风险。
  • 第二步:风险量化,对风险进行评估量化。发生的概率多大?发生后,后果多严重?
  • 第三步:应对计划,对风险制定应对策略。
  • 回避风险——更改导致风险的方案
  • 转移风险——将损失转嫁出去
  • 缓解风险——降低风险发生概率或减少可能造成的损失
  • 接受风险——明知山有虎偏向虎山行
  • 第四步:风险监控,对风险进行监控预警。要做好监控,第一要能对监控的内容量化,第二要设置阈值,第三就是要有后续的报警和处理机制。

7)项目文档

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

  • 帮助写文档的人理清楚思路。先写文档,就会抛开代码细节,去站在全局思考。
  • 便于未来的维护和交接。
  • 便于团队更好的协作沟通。

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

  线框图是最常用也最实用的一种图形,用简单的方框代替功能、模块、服务等,再用箭头表示关系或者数据流向,非常简单直接。要画好线框图并不难,主要是要理清楚有哪些模块,以及模块之间的关系是什么。用方框配上文字表示模块,方框之间的连线和箭头表示关系。


53.png


  流程图是软件项目文档中一种常用图形,可以方便的表示各种不同条件下的逻辑路径。要画好流程图不难,重点是要理清楚逻辑关系,各个关键节点在不同条件下的走向。


54.png


  时序图也是软件项目所特有的一种图形,可以表示不同对象之间发送消息的时间顺序,尤其在涉及网络通信的文档中特别常用。画好时序图,关键是要列清楚所有涉及的对象或者服务,以及消息发送的先后顺序。


55.png


二、需求分析


1)原型设计

  快速原型模型就是,第一阶段确认界面布局和内容,第二阶段确认交互,第三阶段实现。

  • 低保真原型设计,产品经理用线框图来代替第一阶段。
  • 中等保真原型设计,像 Axure 这样专业的原型设计软件产生,不仅可以反映界面上的布局和内容,还可以展示网站的整体结构和交互。
  • 高保真原型设计,对于移动端来说,因为界面比较小,布局和内容上已经没法玩出什么花样。所以客户更追求界面的美观和交互的炫酷,对原型的保真度要求也就越来越高。

2)产品意识

  程序员的价值通常体现在两个方面。

  • 第一,你的价值体现在你所做的产品之上。
  • 第二,你的价值体现在团队中的稀缺性。

  那些价值高的程序员通常在技术上或者技术之外都有一技之长:

  • 有的程序员能搞定别人搞不定的技术难题;
  • 有的程序员擅长培训新人;
  • 有的程序员擅长和业务部门沟通;
  • 有的程序员能高质量地完成功能模块;
  • 有的程序员能按照需求设计好的架构,可以让团队高效率低成本地完成需求。

  产品意识,本质就是一种思维方式,一种站在产品角度思考问题的方式。如果细分一下,产品意识包含:商业意识、用户意识和数据意识。

  • 商业意识,就是所做的产品是要有商业价值的。商业意识的另一方面其实是成本,成本意识也是程序员容易忽视的。比如说:
  • 有时候为了炫技,采用了更难更酷的技术方案,而忽视了所采用的方案会导致很高的开发成本;
  • 花了太长时间去开会而忽略了开会的成本;
  • 有时候又为了省钱,舍不得买一些成熟的商业组件或服务,反而是浪费了更多成本。
  • 用户意识,就是说做产品时,你要能挖掘出用户的真实需求,让产品有好的用户体验。这需要你要有同理心,能站在用户的角度去思考和体验产品。大部分程序员可能更多专注于程序上,所以在用户意识上确实有所欠缺。举例来说:
  • 一个产品功能,产品经理在细节上没有定义清楚,程序员可能并不会主动提出,最终做出来的产品会不好用;
  • 在做技术方案时,更追求技术炫酷,而不是用户体验更好;
  • 在设计接口时,并没有考虑调用者的便利性。
  • 数据意识,就是在产品设计、产品运营时,通过数据来发现问题、证实结果。

  程序员虽然逻辑很好,但是大多对数据倒是不敏感,对编译警告、测试覆盖率、程序 Crash 的比例、API 错误率、一个函数内上千行代码、性能指标等等这些数据经常选择性忽略。

  要培养产品意识,其实和程序员转管理的类似,首先要解放思想,然后要改变习惯,最后要多实践。

  • 解放思想,其实就是说,对于程序员,不要总是单纯的用技术眼光看问题,也可以从产品的角度看问题。技术思维会关注用什么技术,关注技术细节,关注功能“如何”实现;产品思维会关注用户体验,关注一个功能所创造的价值,会去思考为什么要或者不要一个功能。
  • 改变习惯是是指在日常使用产品、开发产品的时候,多站在产品的角度思考,去思考它的商业价值、用户体验、使用场景等等。
  • 不妨在业余时间做个小应用程序,或者设计一个原型,做完了再找你的朋友试用一下,让他们提提意见。在做产品的过程中,你自然会去站在产品的角度去思考,这会让你对产品方面有更多感悟。

3)需求变更

  在需求变更这个事情上,没有赢家,每个人都是受害者。

  目前也已经有很多管理需求变更的解决方案,比如这两个常见的解决方案。

  • 方案一:增强需求变更流程,让需求变更规范起来。
  • 方案二:快速迭代,缩短版本周期。

  既然需求变更的原因是需求不确定和需求变更成本太低,那么我们就针对性地提出相应的解决方案:

  • 提升需求确定性,把需求分析做好,减少需求变更;
  • 提高需求变更的成本,让客户或者产品经理不能太容易就变更需求,这样就可以达到减少需求变更的目的。


三、开发编码


1)技术债务

  技术债务,就是软件项目中对架构质量和代码质量的透支。

  债务的“利息”,就是在后面对软件做修改的时候,需要额外的时间成本。

  处理技术债务策略:

  • 维持:修修补补,只还利息维持现状,只对严重问题修修补补,这其实是常见的一种策略,就跟还债的时候只还利息一样。
  • 重构:新旧交替,分期付款重构相对是一种比较折中的策略,就跟我们采用分期付款的方式偿还贷款一样。
  • 预防才是最好的方法:
  • 预先投资:好的架构设计、高质量代码就像一种技术投资,能有效减少技术债务的发生;
  • 不走捷径:大部分技术债务的来源都是因为走捷径,如果日常能做好代码审查、保障单元测试代码覆盖率,这些行之有效的措施都可以帮助你预防技术债务;
  • 及时还债:有时候项目中,因为进度时间紧等客观原因,导致不得不走捷径,那么就应该把欠下的技术债务记下来,放到任务跟踪系统中,安排在后续的开发任务中,及时还债及时解决,就可以避免债务越来越多。

2)软件工程师的核心竞争力

  软件工程师的核心竞争力,不是单一能力的体现,而是几种能力和价值的合集。学习能力、解决问题能力和影响力构成了软件工程师的核心竞争力。

  • 学习能力:能快速学习掌握编程语言、框架、工具的学习能力才是软件工程师最基础的核心竞争力。
  • 解决问题的能力:软件工程师这些日常开发工作的核心还是在发现问题、分析问题和解决问题,在这里我统称为解决问题的能力。
  • 影响力:需要通过一点点技术成长的积累,需要通过一个个成功项目的积累,需要通过一篇篇技术文章分享的积累,需要通过一次次帮助其他人成长的积累。而一旦形成足够的影响力,就会变成软件工程师职场发展最牢固的护城河。

3)反面案例

  项目管理协会(PMI)认为成功的项目必须满足六个条件:

  • 按时交付。
  • 成本在预算范围内。
  • 能按照当初的设计正常运行。
  • 有人使用。
  • 满足项目最初的目标。
  • 项目出资方对项目满意。

  对于一个失败的软件项目案例,要去分析:外部环境、技术管理、项目管理和组织文化,这样才能帮助你找到项目失败的根源。

  • 对于商业软件项目,很多是由于缩减成本导致的。因为商业竞争的大环境,企业为了节约成本,总是希望用更少的人做更多的事情。
  • 在项目中使用了不成熟或不熟悉的技术,最终导致技术不可控,或者浪费大量的时间在技术的学习上。
  • 项目经理掌握了资源的分配,还要制定项目的计划,对任务进行分配,组织分工协作,管理风险,项目成员的日常沟通等等。一旦这些决策出现大的失误,就会导致项目的失败。
  • 在软件项目中,一个开放、平等、注重沟通协作的团队或组织更容易及早发现和解决问题。

  如果细化一下,还可以总结出一些具体的常见的失败原因:

  • 不切实际或者不明确的项目目标;
  • 对项目所需要的资源估算不准确;
  • 需求不明确或者频繁变更;
  • 没有对风险进行有效管理;
  • 和客户之间沟通不畅;
  • 无法解决项目的复杂性;
  • 没有好的开发实践;
  • 糟糕的项目管理;
  • 上层的政治斗争;
  • 商业压力。
相关文章
|
9月前
|
自然语言处理
[软件工程导论(第六版)]第4章 形式化说明技术(复习笔记)
[软件工程导论(第六版)]第4章 形式化说明技术(复习笔记)
|
9月前
|
算法 数据库 开发者
[软件工程导论(第六版)]第3章 需求分析(复习笔记)
[软件工程导论(第六版)]第3章 需求分析(复习笔记)
|
9月前
软件工程专业初学者计划
软件工程专业初学者计划
|
9月前
|
存储 算法 测试技术
[软件工程导论(第六版)]第9章 面向对象方法学引论(复习笔记)
[软件工程导论(第六版)]第9章 面向对象方法学引论(复习笔记)
|
11月前
【软件工程】软工视频总结
【软件工程】软工视频总结
30 0
【软件工程】软工视频总结
|
11月前
|
敏捷开发 测试技术 项目管理
【软考总结】---软件工程(一)
【软考总结】---软件工程(一)
147 0
|
12月前
|
安全 算法 测试技术
|
12月前
|
机器学习/深度学习 小程序 测试技术
|
敏捷开发 算法 架构师
【备战软考架构师系列笔记 · 001】软件工程篇 —— 软件开发方法的主要分类 ⭐
# 软件开发方法### 分类- 按功能 - 水平原型(针对界面) - 垂直原型(针对复杂算法)
201 0
【备战软考架构师系列笔记 · 001】软件工程篇 —— 软件开发方法的主要分类 ⭐
|
Java 程序员 测试技术
软件工程导论—软件与软件工程(上)
软件工程导论—软件与软件工程(上)
软件工程导论—软件与软件工程(上)

相关实验场景

更多