C# 帮助消除好友/内部成员
我经常看到人们说“如果你需要朋友/内部,那么你的设计是错误的”,有人能告诉我如何重新设计以下代码来消除棋子中的内部。位置 当前使用它是为了在棋盘上添加棋子来设置棋子。要匹配的位置属性,显然将其公开比内部更糟糕,将其私有将阻止棋盘更新位置。谢谢你的见解C# 帮助消除好友/内部成员,c#,oop,friend,internal,C#,Oop,Friend,Internal,我经常看到人们说“如果你需要朋友/内部,那么你的设计是错误的”,有人能告诉我如何重新设计以下代码来消除棋子中的内部。位置 当前使用它是为了在棋盘上添加棋子来设置棋子。要匹配的位置属性,显然将其公开比内部更糟糕,将其私有将阻止棋盘更新位置。谢谢你的见解 public struct Coord { public Coord(int x, int y) { this.X = x; this.Y = y; } public int X { get; private set; } pub
public struct Coord
{
public Coord(int x, int y) { this.X = x; this.Y = y; }
public int X { get; private set; }
public int Y { get; private set; }
}
public class ChessBoard
{
public ChessBoard() { /*[...]*/ }
public ChessPiece this[int x, int y]
{
get
{
// Return ChessPiece at this position (or null)
}
set
{
// Add ChessPiece at this position and set its Location property
}
}
public class ChessPiece
{
public ChessPiece() { /*[...]*/ }
public Coord Location { get; internal set; }
}
我的第一个想法是
- 木板只是一个容器
- 这篇文章有一个公共只读 不变位置属性
- 初始位置设置为单件 建筑
- 通过调用 在工件上移动操作
- 木板只是一个容器
- 这篇文章有一个公共只读 不变位置属性
- 初始位置设置为单件 建筑
- 通过调用 在工件上移动操作
- 我的第一个想法是
- 我个人认为,棋子知道自己的位置很奇怪——这似乎是棋盘的功能,而不是棋子本身。(棋子从桌上取下后在什么位置?通常仍然是有效棋子…)
我将位置/移动逻辑放入棋盘,并为每个有效棋子的位置存储一个
字典。我个人认为棋子知道自己的位置很奇怪-这似乎是棋盘的功能,而不是棋子本身。(棋子从桌上取下后在什么位置?通常仍然是有效棋子…)
我将位置/移动逻辑放入棋盘,并为每个有效棋子的位置存储一个字典
我经常看到人们说“如果你需要朋友/内部,那么你的设计是错误的”
我认为那很愚蠢。朋友和内在存在于语言中是有充分理由的
消除棋子中的内部。位置
这将导致无法更新ChessPiece.Location
如果棋子对游戏有足够的了解,可以更新自己的位置,例如:
public class ChessPiece
{
public ChessPiece() { /*[...]*/ }
public Coord Location { get; }
//a measure of how good it would be to move this piece
public int GoodnessOfBestMove
{
get
{
//calculate what self's best possible move is
... todo ...
}
}
//an instruction to go head and do that move
public void Move()
{
//do self's self-calculated best move, by updating self's private Location
... todo ...
}
}
class Strategy
{
void Move()
{
ChessPiece bestChessPiece = null;
foreach (ChessPiece chessPiece in chestPieces)
{
if ((bestChessPiece == null) ||
(chessPiece.GoodnessOfBestMove > bestChessPiece.GoodnessOfBestMove))
{
//found a better piece to move
bestChessPiece = chessPiece;
}
}
//found the best piece to move, so now tell it to move itself
bestChessPiece.Move();
}
}
关于进一步的细节,有一个叫做“告诉不要问”的OO原则,你可以在谷歌上搜索它
另一种可能性是棋盘将每个棋子存储在棋盘拥有的二维数组中。要移动一块,电路板将该块放入阵列中的不同插槽中;当一个片段想要报告它的位置时,它会在数组中搜索自己
虽然以上都是备选方案,但我并不是说它们一定是解决这个问题的好办法或更好的办法:我不认为我想把游戏策略编码为每一部分的实现细节;相反,我可能有一些非私有的方法让其他类更新每个片段的位置
我经常看到人们说“如果你需要朋友/内部,那么你的设计是错误的”
我认为那很愚蠢。朋友和内在存在于语言中是有充分理由的
消除棋子中的内部。位置
这将导致无法更新ChessPiece.Location
如果棋子对游戏有足够的了解,可以更新自己的位置,例如:
public class ChessPiece
{
public ChessPiece() { /*[...]*/ }
public Coord Location { get; }
//a measure of how good it would be to move this piece
public int GoodnessOfBestMove
{
get
{
//calculate what self's best possible move is
... todo ...
}
}
//an instruction to go head and do that move
public void Move()
{
//do self's self-calculated best move, by updating self's private Location
... todo ...
}
}
class Strategy
{
void Move()
{
ChessPiece bestChessPiece = null;
foreach (ChessPiece chessPiece in chestPieces)
{
if ((bestChessPiece == null) ||
(chessPiece.GoodnessOfBestMove > bestChessPiece.GoodnessOfBestMove))
{
//found a better piece to move
bestChessPiece = chessPiece;
}
}
//found the best piece to move, so now tell it to move itself
bestChessPiece.Move();
}
}
关于进一步的细节,有一个叫做“告诉不要问”的OO原则,你可以在谷歌上搜索它
另一种可能性是棋盘将每个棋子存储在棋盘拥有的二维数组中。要移动一块,电路板将该块放入阵列中的不同插槽中;当一个片段想要报告它的位置时,它会在数组中搜索自己
虽然以上都是备选方案,但我并不是说它们一定是解决这个问题的好办法或更好的办法:我不认为我想把游戏策略编码为每一部分的实现细节;相反,我可能会有一些非私人的方式让其他类更新每件作品的位置。我非常同意史蒂夫的观点。“内部”和“朋友”使用这种语言是有原因的,但这不一定是一个例子
就我个人而言,我在这首曲子上使用了移动(协调)方法。通过这种方式,棋子可以验证其自身移动的有效性(此外,您还可以将派生类用于专门的逻辑,即当兵vs骑士)。坐标应该是不可变的(坐标不移动,并且应该是不可变的,工件移动到新的坐标)
你不应该在任何时候仅仅在黑板上设置一块,这会将你对移动有效性的责任转移到你的调用类。如果需要设置自定义板,请使用新的起始位置创建新板
我也不同意战略方法。我确实同意战略模式在这里是好的,但它不一定要被构建到作品中。我会将策略移动到特定于片段的策略类中。通过这种方式,你的棋子和棋盘简单、干净,可用于人对人游戏,也可用于人对cpu游戏我非常同意史蒂夫的观点。“内部”和“朋友”使用这种语言是有原因的,但这不一定是一个例子
就我个人而言,我在这首曲子上使用了移动(协调)方法。通过这种方式,棋子可以验证其自身移动的有效性(此外,您还可以将派生类用于专门的逻辑,即当兵vs骑士)。坐标应该是不可变的(坐标不移动,并且应该是不可变的,工件移动到新的坐标)
你不应该在任何时候仅仅在黑板上设置一块,这会将你对移动有效性的责任转移到你的调用类。如果需要设置自定义板,请使用新的起始位置创建新板
我也不同意战略方法。我确实同意战略模式在这里是好的,但它不一定要被构建到作品中。我会移动t