Alex Rivera | Logout

How to extend immutable types in Java

Asked 2012-08-04T16:57:15.320
9

I have started playing around with immutable value objects in Java while working on a game project, following the "public final fields" approach:

public class Team {
    public final String name, flag;

    public Team(String name, String flag) {
        this.name = name;
        this.flag = flag;
    }
}

This works pretty well for me so far, but I need different sets of extra information about the team in different circumstances. For example, a team has a set color during a match. The question is, what is the best way to deal with these sets of extended information? I know this is a fairly general question, but I want to keep using immutable objects and that might influence the solution.

Here are the options I have come up with. Most of them are probably "good enough", but I'd like to learn some arguments for and against them for future reference.

Option 1: Everything in one class

public class Team {
    public final String name, flag, colorName;
    public final int colorRgb;

    public Team(String name, String flag, String colorName, int colorRgb) {
        this.name = name;
        this.flag = flag;
        this.colorName = colorName;
        this.colorRgb = colorRgb;
    }
}

This takes only one class for all uses, but there is no type-based indication of what extra data is expected/provided.

Option 2: Subclassing

public class TeamWithColor extends Team {
    public final String colorName;
    public final int colorRgb;

    public Team(String name, String flag, String colorName, int colorRgb) {
        super(name, flag);
        this.colorName = colorName;
        this.colorRgb = colorRgb;
    }
}

This might make a content-based equals() implementation impossible.

Option 3: Composition

public class TeamWithColor {
    public final Team team;
    public final S
Edit
Report

1 Answer

7

As you said. The team can appear in different circumstances. These circumstances are the context giving the team the additional attributes.

Therefore I suggest using composition for each different context that add's data.

public class TeamWithColor {
    public final Team team;
    public final TeamColor teamColor;

    public TeamWithColor(Team team, TeamColor teamColor) {
        this.team = team;
        this.teamColor = teamColor;
    }
}

Maybe you'll have :

public class TeamDuringOlimpics{
    public final Team team;
    public final TeamColor teamColor;
    public final TeamFlag teamFlag;

    public TeamDuringOlimpics(Team team, TeamColor teamColor, TeamFlag teamFlagTeamFlag teamFlag) {
        this.team = team;
        this.teamColor = teamColor;
        this.teamFlag = teamFlag;
    }    
}
answered 2012-08-04T17:24:45.020

Your Answer