具有特定约束的类的设计模式

时间:2014-09-30 13:39:03

标签: object design-patterns class-design

我最近在接受采访时被问到这个问题。我必须为Cricket游戏设计课程,其中将有一个团队,玩家等等。板球队中只能有11名球员。我必须设计这样的类,以便团队可以有一个约束,它只能拥有一定数量的类型的玩家。例如,一个约束可以是一个团队只能有4名击球手,5名保龄球员和2名所有圆场球员。或者一个团队可以约束它可以有3个击球手,6个保龄球员和2个所有圆场。

这样的场景是否有特定的设计模式?

5 个答案:

答案 0 :(得分:2)

没有。

总结(根据以下评论)您最多可以有11名玩家。这就是约束。

我可以通过在构造函数中将两种玩家的数量作为参数来轻松解决 - 例如Team::Team(int batsmen, int bowlers) ---并将另一个数字计算为差异:

class Team {

public:

Team::Team (int batsmen, int bowlers){
    if (batsmen + bowlers > 14) 
         throw std::runtime_error ("Too many players");
    int rounders = 14 - batsmen - bowlers;        
    // Allocate players
}

private:
    std::vector<Batsman> bat_;
    std::vector<Bowler> bows_;
    std::vector<Rounder> rounds_;
};

答案 1 :(得分:1)

要真正说出任何有意义的事情,我需要更多关于游戏和未来的信息。

我只能猜出问题的目标。有一次他们可能会问,如果击球手不应该超过80公斤的限制,该怎么办?)

大致如下:

void Main()
{
    Console.WriteLine("Current team valid: " +
        new Team(
            new List<Player>{
                new Batsmen(),
                new Batsmen(),
                new Batsmen(),
                new Batsmen()
            }).IsTeamValid());
}

abstract class Player {}
class Batsmen : Player{}

class Team {
    static readonly IList<TeamConstraint> DefaultConstraints 
        = new List<TeamConstraint>{new BatsmenConstraint()};

    IList<TeamConstraint> _constraints;
    IList<Player> _players;

    public Team(IList<Player> players) : this(players, DefaultConstraints){}
    public Team(IList<Player> players, IList<TeamConstraint> constraints){
        _constraints = constraints;
        _players = players;
    }

    public bool IsTeamValid(){
        return _constraints.All(constraint => constraint.IsValid(_players));
    }
}

abstract class TeamConstraint
{
    public abstract bool IsValid(IList<Player> players);
}

class BatsmenConstraint : TeamConstraint
{
    const int batsmenRequiredDefault = 4;
    readonly int _batsmenRequired;

    public BatsmenConstraint(int batsmenRequired = batsmenRequiredDefault){
        _batsmenRequired = batsmenRequired;
    }

    public override bool IsValid(IList<Player> players){
        return players.OfType<Batsmen>().Count() == _batsmenRequired;
    }
}

如您所见,约束与Team类是分开的。这样您就可以遵循SOLID原则。

你可以:

1)动态添加新的团队配置

2)动态创建新约束而不修改现有系统。

关于你的问题;没有&#34;板球比赛设计模式&#34;。在尝试解决这个问题时你可以使用几种不同的模式,一个比其他问题更适合这个问题,等等。

我在这里基本上做的是我使用了&#34; bridge pattern&#34;为了

  

将抽象与其实现分离,以便两者可以   独立变化。

当谈到团队与团队之间的关系时TeamConstraint。

答案 2 :(得分:0)

这与特定的设计模式无关。

我认为这样一个问题(特别是在采访中)的一点是你充实了各种设计方案。例如,让我们从

开始
class AbstractPlayer
{ /* stuff */ };

class Batsman : public AbstractPlayer
{ /* stuff */ };

class Bowler : public AbstractPlayer
{ /* stuff */ };

class AllRounder : public AbstractPlayer
{ /* stuff */ };

然后你可以去

class Team
{
public:
    void addPlayer(Batsman player);
    void addPlayer(Bowler player);
    void addPlayer(AllRounder player);

    /* stuff */ 
};

或者它可能是

class Team
{
public:
    void addBatsman(AbstractPlayer player);
    void addBowler(AbstractPlayer player);
    void addAllRounder(AbstractPlayer player);

    /* stuff */ 
};

无论如何你必须决定你是否

  1. 将这些玩家存储在一个AbstractPlayer列表中,并计算不同整数属性中不同玩家类型的数量或
  2. 将玩家存储在三个不同的动态长度列表中
  3. 到目前为止一直很好,现在假设你有Team类中的玩家类型数量。约束在哪里?它们可以在构造函数中设置为三个最大计数

    Team::Team(int maxBatsmanCount, int maxBowlerCount, int maxAllRounderCount) { ... }
    

    或者可能存在某种setter方法(如果对于一个Team实例,数字可能会改变)

    Team::adjustConstraints(int maxBatsmanCount, int maxBowlerCount, int maxAllRounderCount) { ... }
    

    我还有更多可以想到的方法。约束类怎么样?但这取决于Team类的要求。

答案 3 :(得分:0)

您可以使用简单的Specification模式:

class MyTeamPlayersSpecification {

  bool isSatisfiedBy(Team team) {
    // return team.batsmenCount == 4 && ...
  }
}

每次添加播放器时,是否在Team构建或Validate()方法中验证规范取决于问题上下文和您的个人偏好。

答案 4 :(得分:0)

class TeamFactory
{
    static const int bowler;
    static const int batsman;
    static const int allrounder;
    static const int totalPlayer;

    static Team* getTeam(int _bowler, int _batsman, int _allrounder)
    {
        if (((_bowler + _batsman + _allrounder) > totalPlayer) ||   (allrounder condition) || (_batsman condition) || _allrounder condition)
        {
            //  error msg
            getTeam( _bowler, _batsman, _allrounder)
        }
        else
        {
             // create instance,
        }
    }

}