Java Programming – Creating Two-Way Object References and Maintaining Data Integrity

javaprogramming practices

I have two different classes; a Player and a Group. I need to be able to query a Player which Groups they are registered to (player.getGroups()), and which Players are registered to a Group (group.getPlayers()) quickly. The simplest solution is to have each Player keep a list of the Groups it's registered to, and each Group keep a list of all players registered to that group.

This introduces some data integrity problems (how do I ensure that if a Player references a Group, the Group also references the Player) and problems of how to add a Player to a Group.

A solution to the latter problem is to have a single method on either the Player or the Group:

public class Player {

    // ...

    public void registerToGroup(Group group) {
        this.groups.add(group);
        group.addPlayer(player);
    }

    // ...

}

This works, but also introduces some side consequences of modifying the Group you pass, which you might not expect. But maybe this is the best (and relatively simple) way to do it?

What are the best practices for these kinds of problems? I would prefer not have to search through lists and filter out a certain Player to find out which Groups that Player is registered to, and I would prefer to not mix in databases as this is quite a small project but has to be able to be expanded on without much trouble.

Best Answer

First and foremost, determine what is more common in your system - to list groups of a specific player or to list players of a specific group. Depending on which case is more common, implement it accordingly. If you try to implement both equally, you will take a performance hit for both.

So, assumption goes Player belongs to a group, so:

public class Group {
    public void AddPlayer(Player player) {

    }

    public void AddPlayers(IEnumerable<Player> player) {

    }
}

Now that we got that out of the way.

public class Player {
    public Ienumerable<Group> GetRelevantGroups() {
        // Assuming you have some groups provider in this class. You should anyways.
        return this._groupsService.GetGroupsWithPlayer(this.Id);
    }
}

Using both:

// Adding a bunch of players to a group.
myGroup.Add(players);

// Getting all groups for specific player.
var playerGroups = player.GetRelevantGroups();
Related Topic