敏捷开发第6章 一次编程实践

Bob Koss 与 Bob Martin展示结对编程。用TDD的开发模式做一个计算保龄球比赛得分程序。

首先,他们创建了一个测试验收用例。画了一个简单的UML图,便从写测试用例开始编程。

一开始的设计是这样的:

分为三个类:

  1. Game类
  2. Game类包含Frame类,1:10
  3. Frame类包含Throw类,1..3

然后,他们发现不需要Throw类,甚至也不需要Frame类。接着,不断的按功能增加单元测试,单元测试不通过则编写业务代码,通过后再重构,直到代码看上去没有坏味道为止。比如补中与全中的计分功能。整个开发过程是互相提出想法,用代码实践想法,提出修改意见,用代码实践修改意见。

最后代码:

Game:

 1  public class Game
 2     {
 3         int currentFrame = 0;
 4         bool isFirstThrow = true;
 5         Scorer scorer = new Scorer();
 6
 7         public int Score { get { return ScoreForFrame(currentFrame); } }
 8
 9         public void Add(int pins)
10         {
11             scorer.AddThrow(pins);
12             AdjustCurrentFrame(pins);
13         }
14
15         void AdjustCurrentFrame(int pins)
16         {
17             if (LastBallInFrame(pins)) AdvanceFrame();
18             else isFirstThrow = false;
19         }
20
21         bool LastBallInFrame(int pins)
22         {
23             return Strike(pins) || !isFirstThrow;
24         }
25
26         bool Strike(int pins)
27         {
28             return isFirstThrow && pins == 10;
29         }
30
31         void AdvanceFrame()
32         {
33             currentFrame++;
34             if (currentFrame > 10) currentFrame = 10;
35         }
36
37         public int ScoreForFrame(int theFrame)
38         {
39             return scorer.ScoreForFrame(theFrame);
40         }
41     }

Scorer:

 class Scorer
    {
        int ball;
        int[] throws = new int[21];
        int currentThrow;

        int NextBallForSpare { get { return throws[ball + 2]; } }
        int NextTwoBallsForStrike { get { return throws[ball + 1] + throws[ball + 2]; } }
        int TwoBallsInFrame { get { return throws[ball] + throws[ball + 1]; } }

        bool Strike()
        {
            return throws[ball] == 10;
        }

        bool Spare()
        {
            return throws[ball] + throws[ball + 1] == 10;
        }

        public void AddThrow(int pins)
        {
            throws[currentThrow++] = pins;
        }

        public int ScoreForFrame(int theFrame)
        {
            ball = 0;
            int score = 0;
            for (int currentFrame = 0; currentFrame < theFrame; currentFrame++)
            {
                if (Strike())
                {
                    score += 10 + NextTwoBallsForStrike;
                    ball++;
                }
                else if (Spare())
                {
                    score += 10 + NextBallForSpare;
                    ball += 2;
                }
                else
                {
                    score += TwoBallsInFrame;
                    ball += 2;
                }
            }
            return score;
        }
    }

GameTest:

public class GameTest
{
    Game game;

    [SetUp]
    public void SetUp()
    {
        game = new Game();
    }

    [Test]
    public void TestTwoThrowNoMark()
    {
        game.Add(5);
        game.Add(4);
        Assert.AreEqual(9, game.Score);
    }

    [Test]
    public void TestFourThrowNoMark()
    {
        game.Add(5);
        game.Add(4);
        game.Add(7);
        game.Add(2);
        Assert.AreEqual(18, game.Score);
        Assert.AreEqual(9, game.ScoreForFrame(1));
        Assert.AreEqual(18, game.ScoreForFrame(2));
    }

    [Test]
    public void TestSimpleSpare()
    {
        game.Add(3);
        game.Add(7);
        game.Add(3);
        Assert.AreEqual(13, game.ScoreForFrame(1));
    }

    [Test]
    public void TestSimpleFrameAfterSpare()
    {
        game.Add(3);
        game.Add(7);
        game.Add(3);
        game.Add(2);
        Assert.AreEqual(13, game.ScoreForFrame(1));
        Assert.AreEqual(18, game.ScoreForFrame(2));
        Assert.AreEqual(18, game.Score);
    }

    [Test]
    public void TestSimpleStrike()
    {
        game.Add(10);
        game.Add(3);
        game.Add(6);
        Assert.AreEqual(19, game.ScoreForFrame(1));
        Assert.AreEqual(28, game.Score);
    }

    [Test]
    public void TestPerfectGame()
    {
        for (int i = 0; i < 12; i++) game.Add(10);
        Assert.AreEqual(300, game.Score);
    }

    [Test]
    public void TestEndOfArray()
    {
        for (int i = 0; i < 9; i++)
        {
            game.Add(0);
            game.Add(0);
        }
        game.Add(2);
        game.Add(8);
        game.Add(10);
        Assert.AreEqual(20, game.Score);
    }

    [Test]
    public void TestSampleGame()
    {
        game.Add(1);
        game.Add(4);
        game.Add(4);
        game.Add(5);
        game.Add(6);
        game.Add(4);
        game.Add(5);
        game.Add(5);
        game.Add(10);
        game.Add(0);
        game.Add(1);
        game.Add(7);
        game.Add(3);
        game.Add(6);
        game.Add(4);
        game.Add(10);
        game.Add(2);
        game.Add(8);
        game.Add(6);
        Assert.AreEqual(133, game.Score);
    }

    [Test]
    public void TestHeartBreak()
    {
        for (int i = 0; i < 11; i++) game.Add(10);
        game.Add(9);
        Assert.AreEqual(299, game.Score);
    }

    [Test]
    public void TestTenthFrameSpare()
    {
        for (int i = 0; i < 9; i++) game.Add(10);
        game.Add(9);
        game.Add(1);
        game.Add(1);
        Assert.AreEqual(270, game.Score);
    }

原文地址:https://www.cnblogs.com/xiaoguanqiu/p/10465948.html

时间: 2024-09-30 01:52:03

敏捷开发第6章 一次编程实践的相关文章

算法导论第四章分治策略编程实践(二)

在上一篇中,通过一个求连续子数组的最大和的例子讲解,想必我们已经大概了然了分治策略和递归式的含义,可能会比较模糊,知道但不能用语言清晰地描述出来.但没关系,我相信通过这篇博文,我们会比较清楚且容易地用自己的话来描述. 通过前面两章的学习,我们已经接触了两个例子:归并排序和子数组最大和.这两个例子都用到了分治策略,通过分析,我们可以得出分治策略的思想:顾名思义,分治是将一个原始问题分解成多个子问题,而子问题的形式和原问题一样,只是规模更小而已,通过子问题的求解,原问题也就自然出来了.总结一下,大致

读书笔记 -《高效程序员的45个习惯-敏捷开发修炼之道》

<高效程序员的45个习惯-敏捷开发修炼之道> 一本2010年出版的书,当时敏捷还只是在国外开始流行,像我这种菜鸟级根本听都没听过.这次通读了这本书,受益良多,回顾自己的职业生涯,多是漫无目的的瞎混,为了生活而生活而已.通过这本书才算对敏捷有了初步的了解,并有意向敏捷进行实践.愿此文可结识更多敏捷的先行者,带领我进入敏捷的世界. 第一章. 敏捷--高效软件开发之道 名言:  不管路走了多远,错了就要重新返回   -- 土耳其谚语 敏捷开发宣言  个体和交互 > 过程和工具 可工作的软件 &

读书笔记 -《高效程序猿的45个习惯-敏捷开发修炼之道》

<高效程序猿的45个习惯-敏捷开发修炼之道> 一本2010年出版的书,当时敏捷还仅仅是在国外開始流行,像我这样的菜鸟级根本听都没听过.这次通读了这本书.受益良多.回想自己的职业生涯,多是漫无目的的瞎混,为了生活而生活而已. 通过这本书才算对敏捷有了初步的了解,并有意向敏捷进行实践.愿此文可结识很多其它敏捷的先行者.带领我进入敏捷的世界. 第一章. 敏捷--高效软件开发之道 名言:  无论路走了多远.错了就要又一次返回   -- 土耳其谚语 敏捷开发宣言  个体和交互 > 过程和工具 可工

第三次实验报告 敏捷开发与XP实践

一.  实验内容 (一)敏捷开发与XP 摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈.假设简单性.递增更改.提倡更改.优质工作.XP软件开发的基石是XP的活动,包括:编码.测试.倾听.设计. 学习:XP是一种更加灵活的开发方式和理念,通过迅速的反应及时充分修改程序,保证所有团队成员对资源和责任的共享:适用于“小而精”的团队开发.同时,其所倡导的“倾听”也是实现了程序开发“需求至上”的终极目标. (二)编码标准 编码是一个即主观又客观的过程,每个程序员都有他自己的编程

编程心法 之 Scrum - Agile 敏捷开发

Scrum是一种敏捷开发的方法 先定一个能达到的小目标 Scrum 团队 包括产品负责人.开发团队和Scrum Master Product Owner 产品负责人:管理代办事项和优先级的唯一负责人. 相关术语 Sprint 敏捷开发的周期,一般情况下需要2-6周时间,最终应该完成一个可演示给客户或者是可发布的产品 Epic 可以认为就是一个大的Stroy, 还没有拆解, 是对大Story的一个描述性标签 提问:Epic和User Story之间的区别是什么? 回答:准确的说,Epic是比用户故

《高效程序员的45个习惯:敏捷开发修炼之道》

--敏捷开发入门经典-- [内容] <高效程序员的45个习惯:敏捷开发修炼之道(修订版)>总结并生动地阐述了成为高效的开发人员所需具备的45个习惯.思想观念和方法,涵盖了软件开发进程.编程和调试工作.开发者态度.项目和团队管理以及持续学习等几方面. <高效程序员的45个习惯:敏捷开发修炼之道(修订版)>适合所有程序员阅读. [作者] Venkat Subramaniam博士: Agile Developer公司创始人,敏捷开发权威人士.他培训并指导了美国.加拿大.印度和欧洲多国的上

[读书笔记—程序员]《高效程序员的45个习惯:敏捷开发修炼之道》- 苏帕拉马尼亚姆,亨特

虽然不记得阅读本书用了多久,但是整理本书的读书笔记用了两个小时的时间,因为本书的大部分内容对于笔者来说都是新知识,很难进行归纳总结 本书所讲的是程序员应具有的工作态度和在团队中作为开发者和领导者具备的各种"敏捷的"习惯.虽然本书对于程序员的硬实力(本书讲解的编程语言是面向对象类语言,但是讲解的代码非常少)帮助不大,但是对于程序员应该具备的软实力的培养和提高有极大的帮助,是每位程序员都应该反复阅读的书籍. 第一章 敏捷-高效软件开发之道 什么是敏捷开发方法? 2001年2月,17位志愿者

Project Management: 敏捷开发纵横谈

摘要:在IT界中,“敏捷”是一个很酷的词汇,“敏捷”的相关理论可谓铺天盖地.“敏捷”一词实质没有统一定义,各家有自家的说法,本教程将让你了解“敏捷”的来龙去脉,抓住“敏捷”本质,并能在工作中实践“敏捷”. 特别声明:如需转载此文,请给出指向本网站的连接,如下:作者:张传波摘自:http://www.umlonline.cn如不能按此要求,请不要转载此文. 大纲:“敏捷”陷阱为什么会有“敏捷”这个说法?极限编程敏捷开发RUP敏捷开发的实质是什么?如何才能敏捷起来? 正文: “敏捷”陷阱 小甲想到某

瀑布式开发、迭代开发、敏捷开发、XP与SCRUM的区别

瀑布式开发.迭代开发,区别[都属于,生命周期模型]         两者都是一种开发模式,就像设计模式一样,考虑的角度不一样,个人感觉谈不到取代一说. 传统的瀑布式开发,也就是从需求到设计,从设计到编码,从编码到测试,从测试到提交大概这样的流程,要求每一个开发阶段都要做到最好.特别是前期阶段,设计的越完美,提交后的成本损失就越少.我现在从事的外包项目就是这样的流程. 迭代式开发,不要求每一个阶段的任务做的都是最完美的,而是明明知道还有很多不足的地方,却偏偏不去完善它,而是把主要功能先搭建起来为目