我用什么模式相互依存class

What pattern do I use for interdependent class

我从其他来源了解到,让对象相互了解并不是一个好主意,尤其是同一级别的对象。它应该更像层次结构。

我的问题很独特,因为我还没有找到解决方法。我也很不幸遇到任何专门解决我的问题的话题。

问题 我正在构建一个国际象棋应用程序,并且正在构建该应用程序的模型。现在我有一个抽象对象,例如 Piece,其他部分如 QueenKnight 和其他部分将从中继承。 我还有一个 Board class 来处理所有棋盘模型和游戏状态。现在我的每个棋子都有一个 generateMove() 方法来计算从他们的位置开始可能的移动,为此他们需要知道棋盘的状态。此外,棋子在启动时由 Board 实例化。

问题 我是否继续通过例如

实例化 Pieces
public class ChessBoard{
   Boardbit = 64bit
   Knight = new Knight(start_position, this) 

  //calculate

}

然后在骑士class方法

public long generateMove(ChessBoard);

如果不是,我还有什么其他方法可以解决这个问题?

拥有方法 generateMove(boardState) 更好,因此您的董事会应该调用您拥有的任何部分,并向他们传递完成此类任务所需的信息。它甚至可以用于某些优化,因为棋盘可以每轮预生成一些 good-to-use 结构一次,然后将其传递给所有部分(如一些二维数组)。

Chessboard知道Knight,反之亦然并不优雅。在这一点上我同意你的看法。坚持“告诉不要问”规则会强制 'higher level' 元素(在本例中为棋盘)告诉棋子移动,同时提供所有必需的信息。 Chessboard 本身不知道哪个棋子在移动(在这种情况下预测所有棋子可能的移动),但肯定不知道棋子如何移动或允许移动的任何细节。这只是使用某种策略模式的一种可能的解决方案。 (这里也可以使用 Visitor 或一些类似的模式):

Main() {
    chessboard = new Chessboard()
    PiecesCollection = new PiecesCollection(new Knight(KnightStrategy, Color.Black))
    chessboard.AddPieces(PiecesCollection)

    CollectionOfAllPossibleMoveCollections = chessBoard.CallculateAllPossibleMoves()

    Move selectedMove = ShowOrSelectMove(CollectionOfAllPossibleMoveCollections)
    chessboard.ExecuteMove(selectedMove)
}

public class Chessboard{
   // fields
   PiecesCollectionWhite
   // where 'PiecesCollectionWhite' is a collection of `Piece`

   PiecesCollectionBlack
   // where 'PiecesCollectionBlack' is a collection of `Piece`

   CurrentlyVisitedPositionsCollection
   // where 'CurrentlyVisitedPositionsCollection' is a collection of `Position`

   // methods
   AddPieces(PiecesCollection, Color)

   CallculateAllPossibleMoves(Color) {
     CollectionOfPossibleMoveCollections = 
         FOREACH Piece IN PiecesCollection OF Color
             DO Piece.CalculateMoves(this.CurrentlyVisitedPositionsCollection)
     return CollectionOfAllPossibleMoveCollections // where 'CollectionOfAllPossibleMoveCollections ' is a collection that holds a collection of `Move` of which each nested collection represents the possible moves of a chess piece.
   }

   ExecuteMove(Move) {
       RemovePieceFromBoardIfNecessary(Move.ToPosition)
   }
} 

public class Piece 
{
   // fields
   Strategy
   Position
   Color

   // methods
   CallculateMoves(CurrentlyVisitedPositionsCollection) {
       PossibleMovesCollection = this.Strategy.Execute(CurrentlyVisitedPositionsCollection, this.Position)
       return PossibleMovesCollection where `PossibleMovesCollection` is a collection of `Move`
   }
}

public class Knight extends Piece
{
   ctor(Strategy, Color)
}

public class Stragtegy
{
  abstract Execute(currentPosition, allPiecesPositions) : PossibleMovesCollection 
}

public class KnightStrategy extends Strategy
{
  Execute(currentPosition, allPiecesPositions) {
      PossibleMovesCollection = ApplyKnightMoveAlgorithm()
      return PossibleMovesCollection 
  }

  private ApplyKnightMoveAlgorithm() : PossibleMovesCollection 
}

public class Move
{
  Position fromPosition
  Position toPosition
}

public class Color
{
  Black
  White
}

public class Position
{
  Color
  xCoordinate
  yCoordinate
}

这只是一个草图,并不是一个完整的例子。缺少一些状态信息或操作。例如。也许您必须将最后移动的 Color 存储在棋盘上。

由于 Chessboard returns 所有可能的移动(关于所有当前访问的坐标的信息),您可以通过实现一些智能来轻松地增强算法,以根据这些信息预测最佳可能的移动。所以在控制器之前或在这种情况下 Main() 将调用 Chessboard.ExecuteMove(Move) 它可以调用 PredictionEngine.PredictBestMove(CollectionOfAllPossibleMoveCollections).