Friday, February 10, 2012

The Adapter Pattern



The adapter pattern is used to match one interface with another. This is a useful pattern to use when implementing Interface Segregation Principles.

Problem  

I'm building a digital simulator called FarmAnimals that can build farm animals with many capabilities. Some of these capabilities I wish to implement on my own and for others Id like to use an external source like a library. I have found a library called ZooLib that offers animal capabilities that I'd like to use. But the ZooLib library classes implement an interface that is very different to the one implemented by my classes in FarmAnimals. Thankfully there's an Adapter pattern to  the rescue!

Analysis 

I've decided to create a Goat using my FarmAnimals application. FarmAnimals contains an Interface 
IFarmAnimal which defines a method called getDietaryType(). All animals need to eat is a given and so I expect all my animal classes to implement IFarmAnimal.

The ZooLib library has a useful function getFamily() that can help identify the family my animals belong to. I want to use  this feature in FarmAnimals. But my Goat class implements an IFarmAnimal interface and the getFamily which is part of the MountainGoat class in ZooAnimals implements an interface called IZooAnimals which is a completely different interface.

Solution 

Create an abstract base class called ZooAnimalAdapter that implements both interfaces. It delegates all my IFarmAnimal operations to the concrete subclasses in this case Goat and builds wrappers around the IFarmAnimal which are also available as part of my Goat class.

Code


Contents of the ZooLib library

public interface IZooAnimal
{
    void getFamily();
}

public class MountainGoat : IZooAnimal
{
    public void getFamily()
    {
        Console.WriteLine("Family : Bovidae");
    }
}

Contents of my FarmAnimal application

public interface IFarmAnimal
{
   void getDietaryType();
}


public abstract class ZooAnimalAdapter:IFarmAnimal,IZooAnimal
{
   public abstract void getDietaryType();
   public void getFamily()
   {
      IZooAnimal za = new MountainGoat();
      za.getFamily();
   }
}

public class Goat: ZooAnimalAdapter
{
   public void getDietaryType()
   {
      Console.WriteLine("Diet: Herbivor");
   }
}
public class Program
{
   static void Main(string[] args)
   {
       Goat g = new Goat();
       g.getFamily();
       g.getDietaryType();
       Console.ReadKey();
   }
}