Daniel Perez
Daniel Perez

Reputation: 4332

Many to Many relationship in object design

I have a similar problem like this :

Many to many object to object relation in C#

However, imagine that the Championship would have a "Last Date Played" property (just as an example) that would map to any Participant. In this case, where would that property end up? Is it a must to create an intermediate class? (which i wouldn't want to do) what option do i have? thanks!

Upvotes: 0

Views: 1222

Answers (1)

David Mårtensson
David Mårtensson

Reputation: 7600

One way would be to have an array on each object containing pointers to the other objects either via an dictionary that stores the object as key and date as value (or a custom property class for any number of properties) or using a wrapper class around the object and a plain list, this wrapper should then implement the decorator pattern to allow direct access to the object together with any unique properties.

The wrapper object could use an internal object for the properties that is shared between the oposing wrapper objects for the 2 different objects so that any property is in sync.

Another way would be a separate list of pairs where one is wrapped like the above.

The later makes it easy to loop over all objects.

Here is a code example, it might not be exactly what you need but it might give you the basics of my idea.

void Main()
{
    var p = new Player("David");
    var c = new Championship("Chess");
    p.LinkChampionship(c, DateTime.Now);

    p.Dump();
}

// Define other methods and classes here

class Player : Properties {
    public virtual String Name {get; set;}
    public List<ChampionshipWrapper> champs = new List<ChampionshipWrapper>();

    public Player() {
    }
    public Player(string name) {
        Name = name;
    }
    public void LinkChampionship(Championship champ, DateTime when) {
        var p = new Properties(when);
        champs.Add(new ChampionshipWrapper(champ, p));
        champ.players.Add(new PlayerWrapper(this, p));
    }
}

class Championship : Properties {
    public virtual String Name { get; set; }
    public List<PlayerWrapper> players = new List<PlayerWrapper>();

    public Championship(){}
    public Championship(string name) {
        Name = name;
    }

    public void LinkPlayer(Player play, DateTime when) {
        var p = new Properties(when);
        players.Add(new PlayerWrapper(play, p));
        play.champs.Add(new ChampionshipWrapper(this, p));
    }
}

class Properties {
    public virtual DateTime LastPlayed { get; set; }
    public Properties() {
    }
    public Properties(DateTime when) {
        LastPlayed = when;
    }
}

class PlayerWrapper : Player {
    private Player player;
    private Properties props;

    public PlayerWrapper(Player play, Properties prop) {
        this.player = play;
        this.props = prop;
    }

    public override String Name {
        get { return this.player.Name; }
        set { this.player.Name = value; }
    }

    public override DateTime LastPlayed { 
        get { return this.props.LastPlayed; }
        set { this.props.LastPlayed = value; }
    }
}

class ChampionshipWrapper : Championship {
    private Championship champ;
    private Properties props;

    public ChampionshipWrapper(Championship c, Properties prop) {
        this.champ = c;
        this.props = prop;
    }

    public override String Name {
        get { return this.champ.Name; }
        set { this.champ.Name = value; }
    }

    public override DateTime LastPlayed { 
        get { return this.props.LastPlayed; }
        set { this.props.LastPlayed = value; }
    }   
}

Upvotes: 2

Related Questions