typescript 单例类只返回两个示例expressjs

fjnneemd  于 2023-02-13  发布在  TypeScript
关注(0)|答案(1)|浏览(121)

我有一个Player类和一个initPlayers中间件,我试图创建两个玩家示例,这样我就可以在一个简单的石头剪刀布游戏中跟踪他们的分数。

export class Player {
  _score: number;
  private static instance: Player;
  constructor() {
    this._score = 0;
    Player.instance = this;
  }

  addPoint() {
    this._score += 1;
  }

  static getInstance() {
    if (!Player.instance) {
      Player.instance = new Player();
    }
    return Player.instance;
  }
}
export class Game {
  ruleSet: IRuleSet[];
  player1: Player;
  player2: Player;
  constructor(player1: Player, player2: Player) {
    this.player1 = player1;
    this.player2 = player2;
    this.ruleSet = ruleSet;
  }

  whoWins(player1Choice: string, player2Choice: string): { message: string } {
    console.log(player1Choice, player2Choice);
    for (const [_, rule] of ruleSet.entries()) {
      if (player1Choice == rule.choice) {
        if (rule.losesTo.includes(player2Choice)) {
          this.player2.addPoint();
          return {
            message: `Player 2 Wins with ${player2Choice}`,
          };
        } else if (rule.beats.includes(player2Choice)) {
          this.player1.addPoint();
          return {
            message: `Player 1 Wins with ${player1Choice}`,
          };
        } else {
          return {
            message: 'Draw',
          };
        }
      }
    }

    // Return a default value if no match is found
    return {
      message: 'Invalid Choice',
    };
  }
}
// controller
  public play(req: Request, res: Response) {
    const { player1Move, player2Move, player1, player2 } = req.body;
    const game = new Game(player1, player2);
    const result = game.whoWins(player1Move, player2Move);

    console.log('SCORES', player1._score, player2._score); 
    res.render('game', {
      data: req.body,
      player1Score: player1.score,
      player2Score: player2.score,
    });
  }
// middleware to run before route handler which is play()
export const initPlayers = (req: Request, _: Response, next: NextFunction) => {
  req.body = {
    ...req.body,
    player1: Player.getInstance(),
    player2: Player.getInstance(),
  };
  next();
};

当一个玩家获胜时,两个分数都会增加。这是因为当然,两个玩家都指向同一个示例。我在想如何修正这个问题,以便在获胜后分别为每个玩家增加分数。

g52tjvyc

g52tjvyc1#

最简单的设置方法是将Player的两个示例存储在Player类中,然后通过getFirstInstance()getSecondInstance()或类似方法检索它们:

export class Player {
  _score: number;
  private static instance: Player;
  constructor() {
    this._score = 0;
  }

  addPoint() {
    this._score += 1;
  }

  static getFirstInstance() {
    if (!Player.instance1) {
      Player.instance1 = new Player();
    }
    return Player.instance1;
  }

  static getSecondInstance() {
    if (!Player.instance2) {
      Player.instance2 = new Player();
    }
    return Player.instance2;
  }
}

然而,这不是一个好的实践,并且从长远来看,该模式不会是可靠的和可扩展的。相反,您可以将球员存储在一个单独的对象中,该对象也处理初始化,并且可以具有其他相关的方法,如重置分数的方法。
还可以考虑设置一个上下文对象,将值从中间件传递到游戏,而不是将它们添加到请求主体。

相关问题