简体   繁体   中英

Implicit vs Explicit data structures

Lately I've been struggling with some recurrent design problem which I don't know how to solve elegantly.

Say I am making a game with a couple of players and for each player some connected pieces. Together these pieces form a semi-complex collection or structure. Now I could implement this structure in 2 ways: Either store the structure implicitly through pointers in the pieces themselves ie:

class BigPiece extends Piece {
    Piece opposingPiece, nextPiece, previousPiece, index;
}

Or I could implement this structure in a collection class and keep the information centralized:

class SomeCollection<Collection<Piece>> {
    SomeOtherCollection<Collection<Piece>> collection 
        = new SomeOtherCollection<Collection<Piece>>();

    public SomeCollection() {
        collection.add(new PieceCollection<Piece>();
        collection.add(new PieceCollection<Piece>();
        collection.add(new PieceCollection<Piece>();
    }

    public Piece getPiece(int playerIndex, int pieceIndex) {
        collection.get(playerIndex).get(pieceIndex);
    }

    public Piece getOpposingPiece(int playerIndex, int pieceIndex) {
        int nextPlayerIndex = collection.listIterator(playerIndex).nextIndex();
        return this.collection.get(nextPlayerIndex).get(pieceIndex);
    }
}

Now I usually favor the second one, but that's just based on my guts and I don't have that much experience in class design, especially not with big applications. I can see pros and cons on both sides.

The problem I usually have with the first solution is that you still have to create the associations in some builder or factory which actually links the objects together. This doesn't seem very robust to me. Who can reassure me all the pointers are actually correct throughout the application's lifetime?

The second solution centralizes the data more. This really dumbs down the higher classes though (such as individual Pieces). The problem I usually have with this is that whenever I want to traverse this collection, I have to do it on some lower level. You can't ask a piece 'Hey, what's your opposing piece?'. No, you'd have to get a game object to get a pointer to your collection which you then ask what the opposing piece is. This makes more 'managery' classes which collect data from all around your application (method chaining =( ) to finally implement your algorithm. This seems to violate the Law of Demeter .

Sure I could add a pointer to the corresponding collection from each individual piece as well, but I don't know if that's such a good idea since this only seems to be duplicate information.

My personal recommendation is moreso the second option as opposed to the first. As you pointed out, a piece shouldn't (at least in this context) know what its opposing/next/previous piece is.

A manager class would make more logical sense to better facilitate communication between the classes instead of pieces having references to other pieces. I admit I don't fully know about the Law of Demeter but Wikipedia leads me to believe it is all about encapsulation which the manager classes would actually help as well!

I don't think Pieces (again, in this context) should be able to, say, move another piece. However a manager class would logically want to.

That is my suggestion, I hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM