Design Patterns: Adapter

The adapter is used when you want to integrate a class from another source into your code.

It could also be used to enable the use of legacy classes into your new architecture. It can also be used with classes that needs very specific methods to complete some work, like database access classes, and then they could be adapted to use a common interface.

Imagine the following situation

You have a game where all your characters inherit from the abstract class Character.

  1. public abstract class Character  
  2. {  
  3.     public int Health { getset; }  
  4.    
  5.     public int Mana { getset; }  
  6.    
  7.     public abstract string Attack();  
  8. }  
  9.    
  10. public class Link : Character  
  11. {  
  12.     public override string Attack()  
  13.     {  
  14.         return "Link Attack";  
  15.     }  
  16. }  
  17.    
  18. public class Zelda : Character  
  19. {  
  20.     public override string Attack()  
  21.     {  
  22.         return "Zelda Attack";  
  23.     }  
  24. }  

You then need to include a character from another game into your game, but you can’t change the original class. So you can create an adapter for it:

  1. public class Mario  
  2. {  
  3.     public string JumpAttack()  
  4.     {  
  5.         return "Mario Attack";  
  6.     }  
  7. }  
  8.    
  9. public class MarioAdapter : Character  
  10. {  
  11.     private Mario mario = new Mario();  
  12.    
  13.     public override string Attack()  
  14.     {  
  15.         return mario.JumpAttack();  
  16.     }  
  17. }  

This way you can use the new character as if it were just another normal character in your game.

  1. Character link = new Link();  
  2. Character zelda = new Zelda();  
  3. Character mario = new MarioAdapter();  
  4.    
  5. Console.WriteLine(link.Attack());  
  6. Console.WriteLine(zelda.Attack());  
  7. Console.WriteLine(mario.Attack());  

Outputs:

  1. Link Attack  
  2. Zelda Attack  
  3. Mario Attack  

This way it is possible to adapt different classes to use the same interface or abstract class, so your application doesn’t need specific handling for different types.