Java 中的国际象棋 - 面向对象与效率

Chess in Java - Object orientation vs Efficiency

我正在 Java 开发一个国际象棋程序并考虑以下问题:

然而,

我想不出一个干净的解决方案来为这种关系建模,我考虑了一些,但 none 它们都符合良好的面向对象设计 代码高效。

  1. Java不支持多重继承,所以Queen不能借用Rook和Bishop的实现

  2. 如果 Rook 和 Bishop 扩展了 Queen,我需要将每种移动的逻辑提取到单独的方法中,这会严重膨胀我当前关于如何验证移动的设计。

以上解决方案都不够优雅,无法击败:

  1. 将所有运动实现放入所有部件的父级 class 中,这样它们就可以共享 all 通用实现(其中有相当多)

我知道解决方案 3 违反了良好的 Java 设计,但在这种情况下,该设计模式似乎只会强制采用臃肿、不优雅的解决方案。

可能这可以通过完全重组程序来避免,但到目前为止的一切对我来说看起来都非常有效,良好的 OO 设计是否总是以功能和结构的直接性为代价?是不是我的方法不适合语言风格?

你会如何解决这个问题?

Java doesn't support multiple inheritance, so Queen cannot borrow implementation from Rook and Bishop

您不需要多重继承。很多都可以用默认方法模拟。

您可以将这两个方法移至超类,但将它们设为 protected static(您也可以将这些方法放在 PieceHelper 中)。然后在子类中,您可以实现适当的方法,引用这些方法中的一个或另一个(使它们 public)。

超类:

abstract class Piece {
    protected static void moveStraight(Piece p) {...}
    protected static void moveDiagonal(Piece p) {...}
}

(可选)接口:

interface DiagonalMover {
     void moveDiagonal();
}
interface StraightMover {
     void moveStraight();
}

子类:

class Rook extends Piece implements StraightMover {
    public void moveStraight() {Piece.moveStraight(this);}
}
class Bishop extends Piece implements DiagonalMover {
    public void moveDiagonal() {Piece.moveDiagonal(this);}
}
class Queen extends Piece implements StraightMover, DiagonalMover {
    public void moveStraight() {Piece.moveStraight(this);}
    public void moveDiagonal() {Piece.moveDiagonal(this);}
}

虽然一些 classes 可能以类似的方式运行,但这并不自动意味着它们在一个层次结构中!

例如,HumanCrab都可以横向移动,但是Human扩展Crab是愚蠢的。

如果你真的想重复使用移动代码,你可以使用封装,使用 Movement 类型并像这样:

class Human
{
   List<Movement> movements;
}

class Crab
{
    List<Movement> movements;
}

class MoveSideWays extends Movement
{
      move();
}

class MoveForward extends Movement
{
      move();
}

但这感觉像是过度设计。我会用 Piece class 和 getPossibleMoves() 直接实现它。没有太多重叠,Rooks 也有专门的动作(Casling)。

class Rook extends Piece
{
   List<Move> getPossibleMoves()  {...}
}

class Queen extends Piece
{
   List<Move> getPossibleMoves() {...}
}

你不应该对单个片段添加超class-子class关系。 Queen 不是 Rook 的特例,Rook 也不是 Queen 的特例。它们只是不同的部分。您可以创建一个接口(或抽象 class)Piece 并提供不同的实现,如 RookBishopQueen 等。

直线和对角线运动是行为 因此,可以使用比继承更合适的接口对它们进行建模

Rookie 实现 StraightMovement

Bishiop 实现 DiagonalMovement

Queen 实现 StraightMovement、DiagonalMovement