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

Posted xiaoguanqiu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了敏捷开发第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     }
View Code

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;
        }
    }
View Code

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);
    }
View Code

以上是关于敏捷开发第6章 一次编程实践的主要内容,如果未能解决你的问题,请参考以下文章

敏捷开发:原则,模式与实践——第8章 单一职责原则SRP

2017.07.07 IT项目管理笔记整理 第10章 敏捷软件开发

第8章 “敏捷+”创新创业模式

简单之美-软件开发实践者的思考 02

20165310_Exp2实验三《敏捷开发与XP实践》

《敏捷软件开发》第4章测试