C#4.0 & The Decorator Pattern

The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime, independently of other instances of the same class, provided some groundwork is done at design time. (http://en.wikipedia.org/wiki/decorator_pattern)

Design Pattern: Decorator Patten
Pattern Type: Structural
First Stated in: Code Complete, Steve McConnell (1st Edition)
Description: Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.

One of the features of C# 4.0 is the dynamic keyword. Basically used like the var keyword, a dynamic object defers type-checking until runtime. A simple example:

static void Main(string[] args)
{
dynamic pet;

pet = new dog();
Console.WriteLine(pet.kick());

pet = new cat();
Console.WriteLine(pet.kick());

pet = new lion();
Console.WriteLine(pet.kick());

Console.ReadKey();
}

class dog { public string kick() { return "ROWRrr!"; } }
class cat { public string kick() { return "MEOWRrr!"; } }
class lion { public string kick() { return "OmNomNom-"; } }

Make no mistake, that is still fundamentally C#, with all the static type-checking done in the background (mostly in runtime). Anyway, we can also use the dynamic keyword to implement the decorator pattern- which extends a function of a class.

class Program
{
class Zergling { public float cost() { return 1; } }
class BanelingMorph
{
dynamic zergling { get; private set; }
BanelingMorph(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.5f; }
}
class AdrenalGlands
{
dynamic zergling { get; private set; }
AdrenalGlands(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.7f; }
}
class MetabolicBoost
{
dynamic zergling { get; private set; }
MetabolicBoost(dynamic z) { zergling = z; }
float cost() { return zergling.cost() + 0.2f; }
}

static void Main(string[] args)
{
dynamic DevoursChildren = new Zergling();
DevoursChildren = new BanelingMorph(DevoursChildren);
DevoursChildren = new AdrenalGlands(DevoursChildren);
DevoursChildren = new MetabolicBoost(DevoursChildren);

Console.WriteLine(DevoursChildren.cost());
Console.ReadKey();
}
}

I'm doing this while alt-tabbing between Starcraft2 Beta, so forgive the old zergling hero cameo ^^; Anyway, Decorators work a lot like Object "Upgrades", in a sense that they can change the resulting object by modifying functionality. I guess that's done~ Until the next design pattern, Sayonara XD

0 comments:

Post a Comment