1

I'm designing an application whereby there are links and nodes. Each of the two ends of a link is connected to one node and each node can be connected to multiple links.

There are naturally two ways to design the Link and Node classes. The first: Links own Nodes. Nodes will have no knowledge of links.

class Link
{
    public Node First {get; set;}
    public Node Second {get; set;}
    public string Name {get; set;}
    public double Length {get; set;}
    public double Strength {get; set;}
}

class Node
{
    // ...
}

The second: Node owns Links. Links will have no knowledge of nods.

class Link
{
    public string Name {get; set;}
    public double Length {get; set;}
    public double Strength {get; set;}
}

class Node
{  
    public IList<Link> Links {get; set;}
    //...
}

I am not in favor of the second design as it implies the possibility of more than two nodes being connected to the same single link. Furthermore it does not allow a node instance to find its linked partner. If that is the case, unlinking it will be hard (imagine setting the Link property of a node to null - its partner will still hold a reference to the Link)

On the other hand, the first design would imply a need to keep track of the Link instances. Deleting for example a node that is linked would cause a need to explicitly delete the corresponding Link instance (unless we allow the reference to the node in the link to be null - but I want to avoid this as well).

Which do you think, or rather, which is more correct from an OOP point of view?

VMAtm
  • 27,943
  • 17
  • 79
  • 125
Yiyuan Lee
  • 659
  • 8
  • 23
  • I don't think either of approaches is "not correct" - pick one that matches your problem better. – Alexei Levenkov May 28 '15 at 16:45
  • 3
    Keep in mind that in the second example, a node can have multiple links, thus is should have a `List` or any other collection, as one of its properties. – Eminem May 28 '15 at 16:46
  • 2
    I agree with @AlexeiLevenkov: neither is incorrect. And there is a third option: A top level `Map` object "owns" both `Link`s and `Node`s, and handles all manipulation thereof. – RoadieRich May 28 '15 at 16:49
  • 1
    What's te responsibility of a `Link`? If it doesn't do much more than providing a connection between nodes you could use `List` in the node. – venerik May 28 '15 at 16:50
  • @RoadieRich That is not what he is asking. He asks _how_ to implement the `Link` and `Node` classes - using the first option or the second one. In both cases, a `Map` class can be implemented. – Eminem May 28 '15 at 16:51
  • Thanks for all the comments. The link provides a connection between two node instances together with other properties related to the link itself. It can tought of as a rope holding two weights together - while providing the connection it also gives information like the length of the rope and strength of the rope. I have updated the question to be more precise. – Yiyuan Lee May 28 '15 at 16:56
  • Entirely depends on your usage. Are you going to be starting with nodes and moving through links to other nodes? Or are you going to start with links and find the nodes they connect? Or something else. There's also no reason you can't combine both and have the links know which nodes they connect and the nodes know which links connect to them. There are also issues of scale. Are you creating a handful of these nodes and links? Dozens? Hundreds? Thousands? Millions? – Matt Burland May 28 '15 at 17:02

1 Answers1

1

Am I right assuming you are trying to store a graph in memory? If so, there are three approaches how to store it:

  1. Link (edge) list: you are using the first approach, but you can't check two nodes to be connected fast.
  2. Matrix: you are storing two-dimensional arrays (or dictionaries) for your map, but as you have many additional info for Link, I don't recommend this.
  3. Most optimal for you is approach combining both variants: either Link or Node knows about the each other:

    class Link
    {
        public Node First {get; set;}
        public Node Second {get; set;}
        public string Name {get; set;}
        public double Length {get; set;}
        public double Strength {get; set;}
    }
    
    class Node
    {
        public IList<Link> Links {get; set;}
        //...
    }
    

The only problem for this implementation is that you should carefully implement the algorithm to avoid the stackoverflow exception during your operation.

Update:

Community
  • 1
  • 1
VMAtm
  • 27,943
  • 17
  • 79
  • 125