Chess in Java - Object Orientation versus Efficiency

I am developing a chess program in Java and consider the following problem:

  • Part of the rook requires execution to move in straight lines.
  • The bishop element requires execution to move along diagonal lines.

but

  • The Queen part requires implementation for both of the above motion patterns.

I can’t come up with a clean solution to model these relationships, I looked at some, but none of them match good object-oriented design and efficient code.

  • Java does not support multiple inheritance, so Queen cannot borrow an implementation from Rook and Bishop

  • If Rook and Bishop expanded the Queen, I would need to extract the logic for each type of movement into separate methods, this would seriously inflate my current design for how the movement is tested.

None of the above solutions look elegant enough to just beat:

  1. By introducing the entire implementation of the motion into the parent class of all parts, in this way, all of them can share the entire common implementation (which is quite a lot)

I know that solution 3 violates a good Java design, but in this case, this design pattern, apparently, only leads to bloated, inelegant solutions.

This can probably be avoided with a complete restructuring of the program, but until now, everything looks pretty effective for me, does OO design always depend on the directness of functionality and structure? Is my approach wrong for language style?

How would you solve this problem?

+7
java oop chess
source share
5 answers

Although some classes may behave similarly, this does not automatically mean that they are in the same hierarchy!

For example, both a Human and a Crab can move sideways, but it is stupid for Human to expand Crab .

If you really want to reuse the motion code, you can use encapsulation, use the Movement type and do this:

 class Human { List<Movement> movements; } class Crab { List<Movement> movements; } class MoveSideWays extends Movement { move(); } class MoveForward extends Movement { move(); } 

But this is like overdevelopment. I would have a Piece class with getPossibleMoves() and just implement it directly. Too many overlaps, and the Rooks have specialized moves (Castling).

 class Rook extends Piece { List<Move> getPossibleMoves() {...} } class Queen extends Piece { List<Move> getPossibleMoves() {...} } 
+9
source share

You should not add superclass-subclass relationships to individual parts. The Queen is not a special case of the Rook, nor the Rook is a special case of the Queen. These are just different things. You can create the Piece interface (or abstract class) and provide various implementations such as Rook , Bishop , Queen , etc.

+4
source share

You can move both methods to a superclass, but make them protected static (you can also put these methods in PieceHelper ). In subclasses, you can then implement adequate methods by referencing one or the other of these methods (making them public ).

superclass:

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

(Optional) Interfaces:

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

subclasses:

 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);} } 
+1
source share

Direct and diagonal movements are behavior. Thus, they can be modeled using the interface in a more appropriate way than inheritance.

Rookie implements StraightMovement

Bishiop implements DiagonalMovement

Queen implements StraightMovement, DiagonalMovement

0
source share

Java does not support multiple inheritance, so Queen cannot borrow an implementation from Rook and Bishop

You do not need multiple inheritance. Many of them can be modeled using default methods.

-one
source share

All Articles