Over the long weekend I managed to do a little bit more work on the next version of Comicster. I don’t know when this version will ever see the light of day because I seem to be spending as much time ripping code out and rewriting it as I do adding new features! Still, it’s a fun and educational way to pass the time.

In this latest batch of work I have been trying to extract the “online database” functionality out of the core executable and turn it into a MEF extension. That way I can introduce other online databases (such as the new ComicVine API) by copying a DLL into a known folder. In doing so, I’ve employed a pattern (or possibly an anti-pattern) which is working quite well. If you know what its name is, please tell me!

I start by defining an interface which will be the contract that any online database extensions will have to fulfil:

public interface IServiceExtension
{
    Character GetCharacter(string id);
    Creator GetCreator(string id);
    Publisher GetPublisher(string id);
    Trade GetTrade(string id);
    Title GetTitle(string id);
    Issue GetIssue(string id);
}

That’s not the complete interface, but this snippet at least gives us the ability to download the details for all the items that Comicster can track online.

However, to use this interface in a program would be quite clunky. I’d have to do a switch on the currently-selected item’s type, calling the appropriate “Get*” method on the interface. Something like:

if (SelectedItem is Issue)
{
    onlineItem = GetIssue(((Issue)SelectedItem).Id);
}
else if (SelectedItem is Title) ...

That’s ugly code, and I know it must be possible to refactor it to take advantage of the fact that all the known types in Comicster derive from a common class (Comicster.Item). So I plan to add a new abstract method to Comicster.Item, like this (I’ll think of a better name eventually):

abstract class Item
{
    abstract Item GetById(IServiceExtension service);
}

This method, then, would have overrides in classes that descend from Item, like this:

class Issue : Item
{
    override Item GetById(IServiceExtension service)
    {
        return service.GetIssue(this.Id);
    }
}

class Title : Item
{
    override Item GetById(IServiceExtension service)
    {
        return service.GetTitle(this.Id);
    }
}

So each class knows which method to call on IServiceExtension to get a copy of its own “online” version. The program code to download the online item becomes much simpler now:

onlineItem = SelectedItem.GetById(service);

This means that no matter what type the selected item is, it will “know” how to download a copy of itself from the online database service. It’s a little bit like the Strategy Pattern, I suppose, except that each derived class knows how to use the given service in its own way. Is there a name for this pattern? Or is it an anti-pattern? Will it work? What do you think?