快捷搜索:

拉动的力量:一种新的软件生命周期

IT项目的原由很多,然则只有一部分软件能够带来真正的改变。软件开拓是昂贵的,在预算首要时,把钱花在刀刃上就变得非常紧张。

下面的图显示了本文所讲述的新的软件生命周期。这些产出物给每个角色发出旌旗灯号,匆匆使他们创建更多的产出物,直到完成目标并得到商业代价。

最有代价的软件是还没有写出来的软件

Dan North将软件与金属进行了对照。“天生申报”,他说,“就像铅。很轻易获得,还很便宜。但同时也很重,没什么代价,还会拖你的后腿。开拓职员消费大年夜量光阴编写申报软件。为什么不直接买一个、安装上、做一点改动,这样不是也行么?或者应用Excel。除非你是一家贩卖这些软件的公司,否则不要费钱来构建申报软件。

“还有些软件是对照难做的,必要设置设置设备摆设摆设并与第三方交互,但你照样可以购买。这就像铜”。他谈到了子域(subdomains)支持,这个词来自于 Eric Evans的《领域驱动开拓》。这就好比一个核心营业是探求煤油的公司,“他们必要GPS系统。虽然不是每小我都必要这样的系统,然则他们必要,而且还有很多人也必要。那么你可以购买GPS系统,然后集成到你的系统中”。

“是以”,我建议,“假如你有类似的需求,而且这种需求对谁都是一样的,然则还没有人卖,那么你或许盼望能有人帮你做一个这样的产品。”

“当然。”他在卡片上写道:

LEAD

COPPER

Dan说:“这个是铅。我跟CIO们谈谈,问问他们花了若干钱在这上。太多了!”

“那么上面是什么?”我问道。

“上面(左上角)是能快速带来代价的器械。我们有一些软件,它们很轻易构建,而且涉及到你的核心领域。这是Agile实验项目的抱负目标,可视的、高代价的项目,而且没有人做过。本色上来说它们是差异化的。它们有代价,它们是黄金。”

“然后是右上角,这个象限是白金项目。它们很难做,是核心领域,充溢风险而且可能必要和第三方进行交互,异常艰苦的交互,它们是有代价的差异。”

GOLD

PLATINUM

LEAD

COPPER

David Anderson定义了四个商业关注点:商品、差异、节约资源和破坏者。“这是一定的”,我说,“总会有人破坏你的这些差异性-你的黄金和白金项目。他们会盗用你的创意-不必要承担你所承担的风险,由于他们看到它确凿可以应用-然后用更低的资源实现。这便是为什么我们必要敏捷,未来的某一点我们一定要改变,来创建新的差异。”

Dan笑着说:“Chris Matts觉得,构建软件只有三个缘故原由:赢利、省钱、捂钱,这第三个缘故原由异常故意思。LastMinute.com是一个范例的例子,他们经由过程与供应商签署排它性协议赢得了所有的市场-剧院、休闲以及任何他们觉得具有着末刻日,而且人们可以在到期之前取消的器械。回顾起来,LastMinute的设法主见是显而易见的,但当所有人都来分一杯羹时,徐徐缩小的投资回报导致只有很少一部分人能够坚持下来。

“当然,白金项目资源会对照高,由于他们很繁杂,但从这个角度看,它比黄金项目更有代价。”

“好的”,我说,“是以,抱负环境下,我们应该每周或每两周就宣布新的软件版本,我们必要快速相应商业需求。当然,我们知道有些人会破坏我们的器械。是以为了保护我们的钱,我们必要有一个最小商业特点集,它要能使复制的资源异常高昂。而且,需要的繁杂度实际上是好事,它能使我们维持不合……至少在某段光阴内不合。创建一些差异,然后维持这些差异,这便是我们的事情范围。”

现在,我们知道了若何识别紧张的目标和它的范围,下面我们该看看若何实现它了。

愿景匆匆使相干人创建特点集

一旦识别出愿景,最初的相干人会经由过程思虑所有必要介入的人,来确定项目其他的相干人。然后相干人会斟酌他们必要哪些器械来实现愿景。我们平日是用这个模版:

作为……

我盼望……

于是……

我记得Guardian的编辑们应用这种款式,营业阐发师们将之称为“讨要功能”。Chris Matts发清楚明了这个问题,“你将相干人放在了最前面,以是他们会斟酌那些能证实他们的器械。换一种要领,我们可以将愿景放在前面。这样人们就不会添加和愿景无关的器械,有助于削减需求范围的伸展。工作原先就应如斯……”。我将他的建议记了下来:

为了……

作为……

我盼望……

特点集对愿景的依附与开拓职员将依附注入到代码中的要领很相似,并不是由于它是个好主见,而是由于它是必须的,是以有了这个词-“特点注入”。

无意偶尔我们发明,将愿景瓜分成一些小的目标很有用,它们定义了一个终点,而且老是可以回溯到大年夜的愿景。

除此之外,那些提出story的相干人并不老是着末会应用它们的人。Captchas-应用难以识别的图形字母来做图灵测试-便是一个例子。“作为一个用户,我盼望有一个captcha,于是……等等,我不想要captcha,这是挥霍我的光阴”。我们应用模版来写这个story:

为了……

作为……

我盼望……

例如:

为了防止机械人给我的网站添乱

作为论坛的治理员

我盼望用户必须要回答captcha才能写注释。

有些特点以致跟软件不要紧!可能我们的story会包孕如培训、物流、收集治理、司法等器械。相干人平日都邑有软件办理不了的,或者不用软件办理更好的器械,例如LastMinute.com的排他性条约。当我们斟酌愿景时,也必要斟酌这些。

这些故事平日会很大年夜,以至于开拓团队无法处置惩罚或估算。Mike Cohn将之称为“themes”,而特点驱动团队称之为“特点集”,我们也这样称呼它们。

每个特点集的输出-例如,别让机械人来烦我-可能不能只依附一个特点或者一个相干人来实现,我们会在历程中发明,其他的特点集可以实现或赞助同一个产出。当这种环境发生时,我们会再次核阅一下我们的特点集。

特点集匆匆使BA(营业阐发师)创建用户故事

Chris Matts有一个理论。“你知道人们想要什么么?”

“想要什么?”我问道。

“他们向你要求的。你知道他们不想要什么么?”

“不想要什么?”

“你盼望他们要的。你知道还有什么么?”

“还有什么?”

“一旦他们获得了他们想要的,他们就会要的更多。”

从多年考试测验瀑布模型的履历中我们得出,我们很少能够事先预知所有的事,试图在一开始就做对是不完美的。相干人想要一些不合的器械,当我们终于将工作做对了,他们又开始要更多的器械了。

平日,我们在用户故事和特点集上做决准时所处的情况,会跟着光阴而改变,分外是在项目的生命周期内。独一能让我们知道我们对项目的理解是否精确的要领便是尽早获得反馈。获得反馈最好的要领,是给相干人一些他们可以实际操作的器械,他们可以体会用户或其他破费者的体验,并调剂他们最初的设法主见。

为了达到这个目的,我们可以先拿掉落与愿景实质上不想干的器械,即时它是宣布商品或者保护差异的最小特点集的一部分。例如,对付购物车我们只有固定的送货费。改动送货选项或者大年夜宗商品折扣可以放到今后的story中。

斟酌大年夜多半在线市廛都邑有类似的特点集:

为了能贩卖更多的商品

作为收集贩卖的头

我盼望破费者能够在线订购商品,并能收到商品

它可以被分化为多个用户故事:

为了能贩卖更多的商品

作为收集贩卖的头

我盼望破费者能够订购商品为了能贩卖更多的商品

作为收集贩卖的头

我盼望破费者能够将商品放在篮子里而且能够订购篮子(里的商品)为了能贩卖更多的商品

作为收集贩卖的头

我盼望破费者可以改动送货选项为了能贩卖更多的商品

作为收集贩卖的头

我盼望当(破费者的)订单跨越一个最小值时,供给免费送货

当这些被实现出来时,第一个用户故事可以让我们从相干人那里获得美学方面的反馈,让他们斟酌其他用户故事,例如放置相关商品的广告,这可以为项目愿景的实现添加一些不合点。另外的story可以晚一些再添加进来,我们可以从这些用户故事平分手获得反馈。

不是必然非要让BA来编写这些用户故事,不过平日他们对此对照在行。

用户故事匆匆使QA创建场景

当QA测试一个特点时,他们平日会做三件事:

设置利用法度榜样运行的初始状态、数据等

在测试情况中履行一些步骤

反省输出结果

然后他们设置不合的情况,反省不合的输出。

当必要自动化这些场景时,我们可以应用行径驱动开拓(BDD)和场景说话Given、When、Then来定义这些(场景)。

“领域驱动开拓”的作者Eric Evans有一次被问到,场景和用例之间有什么分手。“你无法向营业职员要用例”,我回答,“除非他们懂技巧,知道用例是什么。然则你可以管他们要例子,你可以说‘给我一个场景’”。BDD应用的说话,和DDD中的通用说话,都是为了能够让营业职员和开拓职员可以进行交流。

“有一个满意免费送货标准的购物篮,当我结账时,屏幕上应该显示什么?”

“嗯……这个订单免费配送!”

从对话中,我们发清楚明了新的信息,我们可以用这些信息来写一个例子:

有一个购物篮,里面的商品总价为150欧元

当我进入结账界面后

屏幕上应该显示“此订单免费配送”

QA可以将它作为一个验收测试,QA或开拓职员可以将它自动化。

不是必然非要QA来写这些场景,不过根据我的履历,他们在这方面极为长于。

所有这统统赞助我们确信,当我们开始实现时,我们的代码将有最大年夜的时机为客户带来代价。

不是必然非要让QA来编写这些场景,不过平日他们对此对照在行。

场景匆匆使UI专家设计UI

在我主持的一次回首中,开拓职员识别出,UI专家是阻碍他们完成故事的最大年夜障碍。“从我们第一次见到这个故事,到我们可以开始事情,足足用了三天光阴。”一个开拓职员说道。

“定义页面的样子就必要这么长光阴”,我们的UI专家回答道。

“嗯,”我沉思了一会,“有没有法子缩短这个光阴?或许只做到开拓职员可以事情就行了?”

“可能吧,你必要什么?”

一个开拓职员拿起一张卡片,在上面画了一个草图。“就像这个样子”,他说,“只要能表达网站上显示什么就行了。一旦我们获得了内容,就可以开始写代码,使款式易于改动。”

“很好,”UI专家笑道,“由于我们平日没法一次做对。”

这样,当UI专家忙于创建界面时,开拓职员可以做一些简单然则可以事情的器械。界面的不雅感以致可以作为一个零丁的故事。那些内容-页面上应该显示哪些器械,用户应该点哪个按钮-定义了开拓职员可以开始编写的第一块代码。

UI不必然是图形化的。例如,一个利用法度榜样可以被另一个系统应用,以致没有人会直接查看它的输出。应用它的系统成为了用户,UI专家必要知道什么样的数据才是破费系统必要的。

不必然非要让UI专家来设计UI,不过平日他们对此对照在行。

UI匆匆使开拓职员编写代码

一个刚卒业的开拓职员,Jerry,问我:“我怎么才能知道我的代码是精确的?”

“你怎么知道它不精确呢?”我问道。

“会有人申报一个bug,”他看着QA回答道,“可能是他们,也可能是用户。”

“他们怎么知道那是一个bug呢?”

“他们会应用系统,然则系统没有按着他们必要的那样去做。”

“是的。以是,我们判断你的代码是不是精确的独一要领,便是经由过程用户界面。不管背后有什么,都是支持UI行径,并让我们可以在必要时易于改动这些行径。

”UI是用户体验软件代价的独一道路。创建代码可以应用的界面,是让代码故意义的本色。”

经由过程起开创建UI,并将所有它必要的类打桩,我们可以快速得到UI是否满意商业需求的反馈。我们可以评论争论可能必要改动的器械,我们有更大年夜的时机来创建有代价的软件。假如是另一个系统应用这个UI,我们可以反省两个系统是否能够通信。

代码匆匆使开拓职员编写更多的代码

Jerry编写了界面的代码,他尽力让这一层很薄,并将界面应用的其他类stub out出去。然后,他思虑下一步做什么。“我必要一个数据库表,表中包孕三个列……”

“等一等,” 我建议他,“我们现在就必要数据库表么?我们有什么器械会应用数据库表么?”

“嗯,我们必要应用用户名、邮件地址和用户id来创建用户。”

“做什么呢?”

“这样用户就能经由过程注册界面在网站上注册了。”

“注册界面必要什么器械来赞助它完成注册新用户么?是不是要在界面里做所有的事情?”

Jerry摇了摇头。“那意味着在一个地方放很多的代码,会让改动和掩护变得非常艰巨,而且UI的类也会难以测试,以是我们必要只管即便让它短小。我知道我们必要应用其他的类,在设计模式中平日可以称之为controller或者presenter。”

我们知道我们将来必要改动某些代码,由于Chris说过:“人们老是想要其他的器械”,或者由于营业上的差异性已经变更了。“也便是说,UI必要将实际的事情分配给其他的类。我们现在能否知道我们的Controller将会应用一个数据库中的表?”

“不能……”

“好的,”我说,“让我们想想controller必要做些什么。”

我们将代码分化到不合的类或模块中。单一职责原则是一个好措施。我们可以问问自己,“这段代码应该做什么?不应该做什么?哪些器械是其他类的职责?我们将会若何应用这个类?”假如我们对每一行代码都斟酌这些问题,那么所有的代码都邑变得易于改动。

在单元级别,BDD说话仍旧有用。我们可以应用“应该(should)”来赞助我们将职责拉出来。

“现在,我们知道controller的行径是什么,它若何应用其他的类-user repository和user information,”Jerry说,“我们还知道它应该相应UI的事故。”

我说,“我们可以应用我们的controller写一个fake UI类示例,来描述我们盼望从controller中获得的器械。这可以赞助我们写出能给UI带来代价的起码的代码。作为一个有用的副感化,它还能为我们带来代码的单元测试和阐明文档。”

首先,我们写了示例,或者叫单元测试。然后使用IDE来创建还未创建的类和措施,由于这样对照快。领域驱动开拓(DDD)可以维持设计和代码说话与营业同等,BDD赞助我们关注行径、代价和若何应用类的示例。在发明某些新的、不平常的或者漏掉的器械时,这赞助我们与营业建立有用的对话,而且因为代码的设计和营业维持同等,对代码的改动难度,将与引起这些改动的营业流程改动的难度同等。

当我们完成了对每个类的编码后,我们继承对这个类的相助者编码,直到所有stub出来的类都有一个真正的实现。经由过程这种要领,我们可以包管我们只做了那些可以为UI供给代价的事。我们不会为那些我们觉得将来可能会用到的措施或数据库列来写代码,由于这在当时不是问题。这也赞助我们简化我们的设计。

好的设计可以在我们更深入理解营业流程时,简化代码改动,并为创建UI必要的代价供给更多的选择。就像Chris说的,“在金融领域,选项拥有代价和过韶光阴。真正的选项-真实天下中的选项-也有代价,以及一个再没有选择余地的光阴。无意偶尔,推迟抉择并维持选项是值得的。”好的设计必要更长的光阴,然则这样是值得的,由于它让我们能够推迟决策,或当我们有更好理解时能够改变我们的抉择。

这便是为什么我们应用好的设计实践,和像单元测试与系统测试这样的自动化反馈环,都是为了让修改变得轻易。

不必然非要闪开拓职员来写这些代码,不过假如你正在写,那么你终极会成为一个开拓职员。

我们为下一件最紧张的事做筹备

让我们看一个例子。

有一个简单的愿景:noughts and crosses游戏。出于演习的目的,我们装作没人玩过这个游戏,也没有人看过战斗游戏。我们有一个很大年夜的特点集,叫做“游戏规则”。

我们可以为这个特点集写一个故事。

为了玩Noughts and Crosses

作为一个玩家

我盼望当有三个相同图形在一行时,有一小我得胜

下面是这个游戏的一个场景,以及对应的UI,应用JBehave来自动化:

给定一个这样的网格

OO.

XX.

X..

当玩家点击a3时

网格将会变成

OOO

XX.

X..

并显示“O 赢了!”

下面是定义GameModel应该若何事情的示例代码:

@Test

public void shouldNotifyObserverWhenTheCurrentPlayerWins() {

// 给定一个X将要得胜的结构

GameModel game = new GameModel();

game.playerActsAt(0, 0);

game.playerActsAt(1, 0);

game.playerActsAt(0, 1);

game.playerActsAt(2, 0);

MyGameObserver observer = new MyGameObserver();

game.addObserver(observer);

// 当X得胜时

game.playerActsAt(0, 2);

// X应该是当前的玩家

// 而且X得胜了

ensureThat(observer.game.currentPlayer(), is(Player.X));

ensureThat(observer.game.message(), is(“Player X wins!”);

}

一旦我们完成这些示例,就可以开始编写代码了-GameModel类-来赞助我们使这个示例运行经由过程。

在这个例子中,我们将GUI作为察看者mock出来,应用为这个例子创建的类-MyGameObserver。经由过程mock每个单元的协作者,我们可以包管示例与其他协作者没有耦合,包括那些还不存在的协作者。这让改变变得轻易。

我们没有分数,我们不知道X是不是不停都先走,我们不知道有人得胜后应该若何-我们可能必要重启法度榜样。我们只为这个场景、这个故事、这个特点集和这个愿景写了足够的代码。我们维持代码易于改动,这样就可以在今后为更多的场景和故事添加代码。

当我们完成时,我们就宣布!

当所有的协作者都被真正实现时,我们就写完了这个场景的代码。

当一个故事中的所有场景完成时,我们就完成了这个故事。

当一个theme或特点集中的故事都完成时,我们就完成了这个特点集。

当涉众确认一个愿景的所有特点集都完成时,这个愿景就可以宣布了。

在每个阶段,我们都努力尽快获得反馈

经由过程自动化示例和场景,我们能够发今世码是否能够事情。

经由过程自动化集成和支配到真实情况或相似的情况,我们能够发明是否有之前没故意识到的技巧问题,或者没有斟酌到的涉众。

经由过程尽快给涉众展示利用法度榜样,我们能够发明我们是否可以完成愿景。

在敏捷和精益措施中,还有很多其他的反馈环。这意味着我们在开始事情时要假设可能会犯差错。我们不必要在一开始就包管每件事都是精确的-我们可以从“刚好够用”开始。

在每个阶段,我们都努力削减挥霍

精益临盆努力削减库存-那些还没有安装到可事情的汽车上的零件。用同样的措施,我们努力削减那些没有添加到可事情的特点集和愿景上的用户故事、场景、示例和代码。在看板系统中,旌旗灯号被通报到每个阶段中,这样每个事情站就知道要为下一个事情站临盆一些特定的器械。每个被临盆出来的部分都是由于某个事情站必要他们来满意客户的必要。这便是一个拉动系统。

在其他临盆系统中,临盆线上放着成盒的残剩零部件以备应用。人们必要环抱这些部件事情。这些部件必要掩护、保护、空间等,假如商业需求的改变跨越必然程度,这些部件就要被丢弃。

在一些软件项目中,我们也做了同样的事。我们创建特点集是由于我们有足够的预算。我们对具体阐发那些我们信托会在3个月后必要的故事。我们为我们觉得有趣的特点创建视图。我们创建数据库列和表来存储没有人会应用的信息,以及更多的视图来网络信息。所有这些都必要掩护,必要和他们一路事情,而且在商业需求改变时扔掉落。

经由过程在必要应用时才临盆必要的器械,精益临盆线可以避免这些挥霍。相似的,我们也可以在我们的项目中,经由过程只在必要时才创建来避免挥霍。

这便是我们的拉动软件生命周期

最有代价的软件是还没有写出来的软件。

愿景匆匆使涉众创建特点

特点匆匆使BA创建用户故事

用户故事匆匆使QA创建场景

场景匆匆使UI专家设计UI

UI匆匆使开拓职员编写代码

代码匆匆使开拓职员编写更多的代码

我们做到能够支持下一件最紧张的事

当我们完成时,就宣布。

在每个阶段,我们都努力尽快获得反馈

在每个阶段,我们都努力削减挥霍。

在生命周期中的每个角色都不必要必然是全职的-例如一个开拓职员也可以做BA或QA。在这种环境下,他会带上BA的帽子。假如一小我不斟酌他将从下一个阶段中获得什么-例如代码-那么就险些弗成能获得他鄙人个阶段必要的器械-例如用户故事-是以让不合的人扮演这些角色照样值得的。

不管用什么措施论,老是有不止一种要领来实现同一个目标,不止一种要领来利用措施论,以及不止一种拉动系统得当你。

当Dan North发现BDD时,他说:“法度榜样员想知道从何处开始,测试什么不测试什么,一次测试若干,若作甚测试命名,以及理解测试掉败的缘故原由。”

这个概括应该能让你知道从何处入手,什么好用什么不好用,一次应该做若干,若何称呼正在做的事,以及若何在软件生命周期的每个层次得到反馈;这样不管编写什么软件,都是好的软件。

您可能还会对下面的文章感兴趣: