跳转至

项目管理

边写边改模型 Code And Fix

1960 年初,软件开发属于混沌无序的起步阶段,编程语言以汇编为主,功能都比较简单,开发模式就是边写边改。

但随着需求越来越多,功能越来越复杂,再加上开发人员水平参差不齐,人数变多,无法一起有效协作,软件质量也无法得到保证,继而导致了软件危机。

瀑布模型 Waterfall

1970 年,Winston Royce 博士借鉴了其他工程领域的思想,提出了瀑布开发模型,类似于工业界第一次提出流水线,让软件开发过程变得有序可控,每个阶段都有明确的任务和交付产物,使软件开发有了生命周期(Software Develop Life Cycle, SDLC),协作分工变为可能:项目经理、产品经理、架构师、软件工程师、测试工程师、运维工程师。因此很快便传播应用到各种软件项目中,即使瀑布模型如今已不再是主流的开发模式,但其核心思想依然影响深远。

20240511105817

在项目立项后,产品经理首先和客户或者老板充分的沟通,了解甲方的想法是什么,要做一个什么样的产品。然后市场调研,设计原型,与甲方反复沟通确认。然后落实到产品设计文档,将产品划分为不同的模块,以及每个模块的具体功能。

需求评审之后

  • 架构师开始做架构设计,确认技术方案,拆分功能模块,分工
  • 设计师开始设计 UI,与产品一起设计交互
  • 测试,分工,根据产品文档编写测试用例

前面一个步骤不完成,后面的步骤不能开始,否则问题会滚到下个阶段,带来更多的问题,无法适应需求的频繁改动

迭代模型

迭代模型本质上是一个小瀑布模型,所以在一个迭代里面,需要完整的经历从需求分析,到设计、编码、测试这几个完整的阶段。

20240522203132

敏捷开发 Agile Development

2001年,为了解决瀑布模型这样重型软件开发方法存在的问题,17 个轻量级软件开发过程流派的领军人物聚集在一起吃饭、聊天、滑雪,史称雪鸟会议,讨论试图用一种轻量的、敏捷的方法来改善甚至是替代它。但最终没能达成一致,所以退而求其次,把大家都认同的理念整理出来,形成了敏捷宣言,还一起成立了敏捷联盟。

我们熟知的 Martin Fowler 是敏捷的支持者和普及者之一

20240511163329

也就是说,敏捷开发其实是一套价值观和原则,属于「道」,具体的「术」由各种敏捷框架、方法论和工具来实现,进一步说,当你开发做决策的时候,遵守了敏捷开发的价值观和原则,不管你是不是用了敏捷框架或工具,那么都可以算是敏捷开发。

常用术语

  • Backlog 需求池,任务清单
  • Story 用户故事,小目标
  • Task/Issue/Ticket 分配给每个开发的子任务
  • Sprint 完成某个目标的迭代周期
  • Release 可用版本

像站会、看板、持续集成、测试驱动开发、结对编程等都来自于敏捷开发。

瀑布模型的典型问题就是周期长、发布烦、变更难。敏捷开发就是快速迭代、持续集成、拥抱变化。

敏捷追求的不是快,而是要取得具体、可度量的进展,要取得可靠的数据。目的是从数据上更早地发现项目出现问题的点,让团队成员向着同一目标前进。

敏捷开发的需求,主要是来源于一个个小的用户故事,用户故事通常是写在卡片上的一句话,在 Sprint 的开发中,再去确认需求的细节。

在敏捷开发中,并不是基于完整的用户需求开发,每个 Sprint 只做一部分需求,所以是一种渐进式的架构设计,当前 Sprint 只做适合当前需求的架构设计。但迭代次数一多,就会出现架构满足不了需求的现象,产生不少冗余代码,即所谓的技术债,需要定期对系统架构进行重构。

增量迭代,小步快跑。

敏捷发展至今已经有无数分支,有些甚至已经偏离了敏捷思想。

Scrum 和 XP 都是基于敏捷方法论下的指导框架

Scrum

迭代中不允许改变项目计划,迭代结束之后,才可以根据实际反馈做相应调整

周期一般是 2-4 周,相对较长

20240521110704

会议

  • Sprint Plan Meeting 冲刺计划会议
  • Daily meeting 每天的站会,或者直接叫 Scrum
  • Sprint Review meeting 评审会议,让团队成员们演示成果
  • Sprint Retrospective Meeting 回顾会议

极限编程 XP

Extreme Programming(极限编程,XP)

极限编程是敏捷本质核心的原型,也是最好的代表,在所有敏捷过程中,极限编程是定义最完整且清晰地,可以说其他的敏捷过程都是极限编程的子集或变体。

要求实际项目任务要严格遵守用户故事的优先级

https://teobler.com/posts/20210201-agile-business-practice-planning-games

20240522100842

敏捷宣言中的每一句话都能在生命之环中找到体现的实践

最外层,业务实践,也是 Scrum 最初的构想,业务和开发团队间管理和沟通的框架

https://teobler.com/posts/20210207-agile-three-business-practice

  • 完整团队(Whole Team) 最初是现场客户(在团队中加入一位真正的、起作用的用户,他将全职负责回答问题),后来改为了完整团队,同一个团队中应该有客户、业务分析师、程序员、测试人员、经理等等。同时这些角色应该尽量处于同一个办公区,目的是缩短角色之间的物理距离,提高团队效率,打破职能壁垒。
  • 计划游戏(Planning Game) 快速制定计划、随着细节的不断变化而完善
  • 小型发布(Small Release) 系统的设计要能够尽可能早地交付,持续交付(Continuous Delivery, CD)
  • 验收测试(Customer Tests)

中间层,团队实践,开发团队内进行沟通和管理的框架

https://teobler.com/posts/20210214-agile-team-practice

  • 编码标准(Code Standards) 强调通过指定严格的代码规范来进行沟通,尽可能减少不必要的文档
  • 可持续的节奏(Sustainable Pace) 每周工作时间不超过40小时,加班不得连续超过两周,否则反而会影响生产率
  • 隐喻(Metaphor) 其实应该叫统一语言(Ubiquitous Language),不论是在代码中还是在讨论的时候大家都能在同一个上下文里
  • 持续集成(Continuous Integration, CI) 可以按日甚至按小时为客户提供可运行的版本
  • 集体所有权(Collective Ownership) 任何团队成员都可以随时改善项目中的任意模块,既要在自己擅长的领域工作,还要与其他领域的代码打交道

最内层,技术实践,用来约束和指导程序员们,来确保得到最高的技术质量,是敏捷的核心,每一项单独拎出来都能写一本书

https://teobler.com/posts/20210221-agile-technology-practices-tdd

  • 结对编程(Pair Programming) 由两个程序员在同一台电脑上共同编写解决同一问题的代码
  • 测试驱动开发(Test-driven Development) 先写测试代码再编写程序,建立重构的基础和信心
  • 重构(Refactoring) 在不破坏任何测试的前提下对命名、类、函数和表达式等进行修改,来改善系统的结构。理论上重构应该是日常开发中时时刻刻都在进行的活动,而不应该是单独拿出来花时间做的一件事情,也不应该出现在项目的计划中。
  • 简单设计(Simple Design) 仅编写必要的代码,使得程序结构保持最简单、最小和最富表现力,也是重构的目标之一

工作流可视化

甘特图(Gantt Chart)

以其提出者名字命名,也可称作横道图或条状图。

20240619200449

看板 Kanban

通常有几个状态:Backlog、To Do、In Progress、Testing、Done

20240619200721

燃尽图 Burndown Chart

随时间递减的曲线,用于追踪项目进度

  • 横轴:持续时间
  • 纵轴:剩余故事价值总数、任务预计总工时等。

燃尽图通常有两个曲线:

  • 预估的下降曲线
  • 实际的下降曲线,表示在某个时间实际剩余的价值或工时等。

如果实际曲线在某时刻高于理想曲线,则表示目前进度是落后的;相反,如果实际曲线低于理想曲线,说明进度是领先的。

测试驱动开发

20240521184149

TDD

TDD(Test Driven Development),测试驱动开发,一个经常被提及但很少被执行的开发模式,先编写测试,然后编写能够使测试通过的代码。

也有人认为 TDD 是 Test-Driven Design,先编写测试,驱动你设计出更易与测试的代码,强迫你写出低耦合的代码。

具体由谁来编写测试代码呢?如果是 RD 来写,则他们会以技术思维来写,而且面对描述不清的需求文档,并不能精确的知道每一处细节,另外很多程序员连单元测试都懒得写,更何况在编写代码之前先写好测试用例了,而如果由 PM 来写,则大部分业务方并不具备编码能力,即使懂技术,也可能与 RD 使用的技术栈不一致。

20240514133301

BDD

于是便催生出一些工具和方法论来解决这些问题,比如 JBehave、Cucumber 等。

2003 年 Dan North 重新定义了 TDD,提出了 BDD(Behavior Driven Development),行为驱动开发,让业务方可以不写测试,但是希望他们能够以一种形式化的、基于场景的语言(比如 Given-When-Then)来详细描述他们的系统,这样的语言对程序员编写测试也有巨大的价值。

20240521182742

e.g.

  • Given the user has entered valid login credentials
  • When a user clicks on the login button
  • Then display the successful validation message

然而最适合的其实还是 QA,他们是既了解业务又拥有很强技术的人。能够站在业务和用户的角度找出如何破坏系统的方法,同时他们还能了解程序员的思路,戳穿他们的偷工减料。

ATDD

ATDD(Acceptance Test Driven Development) 验收测试驱动开发

20240521182811

DDD

DDD(Domain Drive Design) 领域驱动开发