Accessing parent elements in an object model efficiently

I have a following object model:

- Book 
-- Chapter 1
--- Page 1
---- Image 1 
---- Image 2
---- Text 1
--- Page 2 

Resources are way down at the page level. But, I need to know the full path to resources, from the resources' point of view.

One way, is to have resources be aware of their parents.

So my Image object could have a "parentPage" property, which in turn could have a "parentChapter" property. This way, I could access the complete path via currentImage.parentPage.parentChapter. Is there a better way?

A couple of words on why I'd need to know the full path from a resource's point of view. I have an object model that gets walked and rendered on screen. The renderer descends from chapter level all the way down into the element/resource level (this is where the rendering occurs). However to display the resources, I need to know where they live (ie the actual path on disk) and this information is typically specified at the Chapter level.


-- Edit -- Just to clarify, is this parent.parent approach the best? It forces child objects to know about the parents, which makes me uncomfortable. Coupling?


Whether or not you use Zachary's tree structure or you do it in a more type-specific way, the question about coupling lives on.

If there is a lot about an image that doesn't have anything to do with how the image is "hosted" in a page, you might want to use an intermediate type which has the context-dependent aspect and that contains an image instance (reference).

Only you can decide if that is excessive, depending on the application and how important it is to reduce coupling and allow greater reuse of some of the constituents in other contexts.

I'd suggest a tree structure, whereas each of your classes inherits from a tree node.

Example in c#:

class TreeNode {
 public TreeNode Parent { get; set; }
 public List<TreeNode> Children { get; set; }

class Book : TreeNode {
 ... book attributes ...

... other classes ...

Actually, if you're worried about coupling the thing to ask yourself is it good coupling or bad coupling? If the coupling actually adds value and there is a logical reason to do it, do it. If not, it's wasted code. If you're using a language that supports generics, you can decouple it a little farther:

class TreeNode<TParent, TChild>  
    public TParent Parent { get; set; }
    public List<TChild> Children { get; set; }

class Book : TreeNode<object, Chapter> { }
class Chapter : TreeNode<Book, Page> { }
class Page : TreeNode<Chapter, object> { }

Hope that helps!

Sounds like you want a doubly-linked list or possibly to even consider using a tree structure.

You may be able serialize the object to xml and use linq to xml for parsing the information.

If you must use instances of objects, another option may be to look at the composite pattern (see wikipedia)


Need Your Help

Nesting or Referencing Queries in Postgres

sql database postgresql join nested

I'm having trouble understanding nested queries. I have a comments table and a posts table and I want to count the number of comments in a given date range for a given site. This part I can do fine...