Cantabrigian
Cantabrigian

Reputation: 13

Property of one class is another class, and vice-versa

I'm programming a board game in C# where the two most important classes are Piece and Square. Typically every instance of Piece has a Square (as a property) and every instance of Square may have a Piece (also as a property) or may be empty.

I placed code in the set methods of Square.Piece and Piece.Square to ensure that this relationship was maintained (e.g. when a piece is moved from one square to another) and to avoid the obvious danger of the linked properties calling each other's set methods in an endless loop.

But when a piece is removed from the board and its square set to 'null' I seem to have too many if statements to avoid null exceptions and what seemed a very simple pattern conceptually becomes far too complex and error-prone in practice.

I'm wondering whether my whole approach is wrong. Should a piece have a square as a property when Square also has Piece as a property? Have I in fact started coding an anti-pattern? A Piece's Square may be null on creation, and a Square's Piece is frequently null (representing empty). Should I use another way to represent empty Squares and Pieces which are not on the board?

I'm assuming there are preferred, robust solutions to the more general case of when one class is linked to another in a two-way relationship such as this.

Many thanks for any ideas.

Upvotes: 1

Views: 276

Answers (2)

Joe White
Joe White

Reputation: 97656

It seems to me that you're overthinking the process of removing a Piece from the Board.

The game is going to be centered on the Board class. Once you remove a Piece from the Board, that piece is gone; you're not going to do anything with it anymore. You won't be calling any of its methods or anything. That object is now dead -- unreachable. So there's not actually any reason to change the Piece's state to null out its Board reference.

This is indeed a very common pattern, and the usual practice is to just let it go. Once nobody references the Piece anymore, you're done; it no longer matters that the Piece still happens to reference the Board. Let it keep its reference; it won't cause any harm (since nobody will be doing anything with that Piece anymore), and it'll be garbage collected soon anyway.

Upvotes: 1

SJuan76
SJuan76

Reputation: 24780

Use an higher level abstraction, with methods like

  • move(piece, originalSquare, destinationSqueare)
  • place(piece, square)
  • remove(piece)
  • promote(originalPiece, finalPiece)
  • ...

these methods will use your basic methods from Piece and Square, and will be the ones used by your main logic

Upvotes: 2

Related Questions