网球卡塔的州设计模式用法

时间:2018-03-23 13:15:56

标签: java design-patterns

我正在解决着名的Tennis Kata Problem

我对州设计模式有一个基本的问题。 该计划需要输出网球比赛的分数。

低于enum代表网球游戏中玩家可以拥有的不同分数:

public enum Score{
Love,
Fifteen,
Thirty,
Fourty,
Deuce,
Advantage,
Game
}

我打算在这里使用的典型课程是: TennisGame(处理逻辑的主要类),Player(将维持自己的分数),ScoreCalculator(根据规则具有分数操作逻辑) 当外部事件发生时,分数将被更改,这表明哪个用户已经得分。

这里的问题是 - 如何处理跟踪分数变化的逻辑?

非常天真的做法是:

if(score == Love){
  score = Fifteen; //move score to Fifteen 
}else if(score == Fifteen){
  score = Thirty; //move score to Thirty
}

但这会导致很多其他条件。 我想为此使用状态模式。

但问题是,这里的上下文(例如:TennisGame类)将封装State并不会根据状态变化做任何事情。

一旦球员得分,只需返回得分。

有人可以在这里使用状态模式建议正确的设计吗?

1 个答案:

答案 0 :(得分:1)

首先,我认为您的分数枚举中不需要Deuce,因为这是分数为40-40时的状态。在这种情况下,如果你有得分为30-40的情况,并且如果玩家得分,那么你必须改变两个玩家的状态。这将很难管理。从我的角度来看,这是最好使用的枚举:

public enum Score {
    Love, Fifteen, Thirty, Forty, Advantage, Game
}

我认为第二件事是更好的是不保存当前的球员得分,而是存储两个球员的赢球数,然后你可以根据这些数据计算得分。使用以下代码很容易实现:

public Score calculateScore(int playerWinBalls, int opponentWinBalls) {
    if (playerWinBalls <= 3) {
        return Score.values()[playerWinBalls];
    }
    int winBallsDifference = playerWinBalls - opponentWinBalls;
    if (winBallsDifference <= 0) {
        return Score.Forty;
    }
    if (winBallsDifference == 1) {
        return Score.Advantage;
    }
    return Score.Game;
}

现在剩下的就是拥有一个增加API来赢得给定球员的球,它可能是某种方法,如winBall(String playerName),有winBallP1()/winBallP2()等单独的方法,或者其他方法。