Entity Framework 4.0: On the way to Composite Pattern

In my last posting about Entity Framework 4.0, Entity Framework 4.0: POCOs and table-per-type inheritance mapping, I made first generalization to my photo gallery model. I introduced GalleryItem class that is base class for all that can be added to gallery: new albums, photos and maybe videos too. Although everything works as expected my model needs some modifications because it is not very foolproof.

Analyzing current model

Let’s take a look at current model. Currently album is self-referencing class. It was okay because albums may have sub-albums. Also albums my contain photos and we had also association from Album to Photo.

Classes of my gallery

But there are some nasty side effects:

  • Album contains direct association to Photos. When we add new class for videos then we must add new association to Album class. All queries for Album children go more complex because we have to query ChildAlbums, Photos and Videos. Think about gallery items view where nine items from current album are shown ordered by date.
  • Adding new classes to model that extend GalleryItem mean that we have two database relations per table: one from GalleryItem to new table and one from Album to new table.

Somehow we have to protect Album class so it doesn’t grow as new descendant is added for GalleryItem.

Solution

To solve our problem we need some modifications. We will move ParentAlbum property from Album class to GalleryItem class. This guarantees that every item in gallery may have parent album. If we have new class called Video that extends GalleryItem then Video gets parent album automatically.

Gallery classes almost following composite pattern

As you can see from new model diagram then we don’t need association from Album to Photo anymore. We can easily add new classes that extend GalleryItem and we don’t have to change other classes. Also all classed based on GalleryItem have ParentAlbum property.

On Entity Framework 4.0 everything works fine. I changed my classes and my mappings a little bit and everything works now as expected.

Code

So, here is the code of classes and it is exactly what I wanted.


public abstract class GalleryItem
{
   
public virtual int Id { get; set
; }
   
public virtual string Description { get; set
; }
   
public virtual GalleryItem ParentAlbum { get; set
; }
   
public virtual string Title { get; set
; }
   
public virtual bool Visible { get; set
; }
}

public class Album : GalleryItem
{
   
public virtual ICollection<GalleryItem> ChildItems { get; set
; }
}

public class Photo : GalleryItem
{
   
public virtual string FileName { get; set
; }
   
public virtual bool IsGalleryThumb { get; set; }
}

As you can see then Album class contains now only one automatic property. Although we should be more careful here (everybody can assign new value to ChildItems collection) I don’t have problem with it right now. When I discover the problem then it is time to find a solution.

Why not composite pattern?

Reader who knows patterns can see here Composite Pattern. At least our associations are made this way but GalleryItem misses some methods. I know that and I don’t even consider using Composite Pattern here. Why? Because I really don’t need it right now.

Okay, many i-know-everything gurus, idealists and other maniacs will scream now divine revelations of dark doom of my model and my application. It is blasphemy in this point not to use Composite Pattern. If these guys knew where I live then they were considering next crusade. But don’t care about them.

This far I have used my common sense to go on step by step. I’m not swimming in safe waters and most of my work here is experimenting. That’s why I don’t put any efforts to ideal architecture and packaging right now. Also there is no point to implement any pattern just because something almost looks like following this pattern.

Of course, I don’t abandon Composite Pattern completely. I made a note to my private development Wiki that there is something very similar to Composite Pattern. That’s enough for now. As a first thing I try to use the new architecture in my code.


Leave a Reply

Your email address will not be published. Required fields are marked *