Adapter Pattern

posted on 03/22/06 at 11:47:51 pm by Joel Ross

I've been slowly reading a book on Design Patterns, but I've recently started looking at dofactory.com, mainly because it has it's samples written in C#. It's odd how a description can seem so vague, but seeing code crystalizes the concept. Well, that's exactly what happened when I took a look at the adapter pattern. Reading about it, it sort of made sense - I know what the concept of an adapter is, and I can relate that concept to programming, and come up with...something. Taking an object and adapting it to my current system. Yeah, that makes sense, right?

It does when you see it in code! Once I saw it, the possibilities seem endless. To me, it's a great pattern for integration. Let's say you have a system that can handle your type of order, and you need to integrate with another system, which uses a similar, but different order object. So how do you do it? With an adapter! It's the least impactful to the existing system, and get's you the result you want - integrating disparate systems.

The description makes sense, but let's look at code, since that's what cleared up the fog for me. First, the client that interacts with orders:

   1:  List<Order> orders = OrderManager.GetOrders();
   2:  ?
   3:  foreach(Order order in orders)
   4:  {
   5:      order.Save();
   6:  }

Nothing special, but the client knows how to get orders, and how to save an order. Now, here's what an order looks like:

   1:  public class Order
   2:  {
   3:      private string _orderId;
   4:      public virtual string OrderId
   5:      {
   6:          get { return _orderId; }
   7:          set { _orderId = value; }
   8:  ?
   9:          public virtual void Save()
  10:          {
  11:              Data.Save(this);
  12:          }
  13:      }
  14:  }

Again, nothing special. You can go on working like this forever. Until you buy a company, and all of?a sudden, you're dealing with an order from their system:

   1:  public class CompanyOrder
   2:  {
   3:      private string _id;
   4:      public string ID 
   5:      {
   6:          get { return _id; }
   7:          set { _id = value; }
   8:      }   
   9:  ?
  10:      public void Commit()
  11:      {
  12:          Data.Commit();
  13:      }
  14:  }

So what do you do? Do you rewrite your order processing system to accept both Order objects and CompanyOrder objects? Do you rewrite the new system to use Order objects rather than CompanyOrder objects? Or do you write an adapter to link one to the other?

   1:  public class NewOrder : Order
   2:  {
   3:      private CompanyOrder companyOrder;
   4:  ?
   5:      public NewOrder(CompanyOrder companyOrder) : base()
   6:      {
   7:          this.companyOrder = companyOrder;
   8:      }
   9:  ?
  10:      public override string OrderId
  11:      {
  12:          get { return this.companyOrder.ID; }
  13:          set { this.companyOrder.ID = value; }
  14:      }
  15:  ?
  16:      public override void Save()
  17:      {
  18:          this.companyOrder.Commit();
  19:      }
  20:  }

Now you just change the OrderManager to know how to get the new CustomerOrder objects, and add those to the collection (as NewOrder objects), and the client can now interact with the new system's orders.

And that, my friend, is the adapter pattern.

Categories: Development