Ayende @ Rahien

Hi!
My name is Oren Eini
Founder of Hibernating Rhinos LTD and RavenDB.
You can reach me by phone or email:

ayende@ayende.com

+972 52-548-6969

, @ Q c

Posts: 5,955 | Comments: 44,412

filter by tags archive

Design patterns in the test of timeAdapter


In computer programming, the adapter pattern (often referred to as the wrapper pattern or simply a wrapper) is a design pattern that translates one interface for a class into a compatible interface.

More about this pattern.

This pattern is the first of the first of the Structural Patterns in the G04 book, and for the most part, it is meant to be used solely when you are integrating two or more external systems / libraries. When I saw it used inside a system, it almost always a Bad Thing, mostly because inside a single system, you want to use one of the other structural patterns.

HttpContextWrapper is a good example of using this pattern, and it links back nicely to the previous discussion on Singletons. HttpContext.Current was an issue, because it didn’t allow easy overriding / mocking / testing. The new HttpContextBase class was introduced, but due to backward compatibility concerns, HttpContext’s base class could not be changed. The solution, introduce HttpContextWrapper implementation that adapts between the two.

Useful pattern, but all too often people try to use it to abstract things, and that is most certainly not what it is meant for.

Recommendation: Use when you need to integrate with code that you can’t change (3rd party, legacy, compatibility concerns) using a common interface, but avoid otherwise.

More posts in "Design patterns in the test of time" series:

  1. (21 Jan 2013) Mediator
  2. (18 Jan 2013) Iterator
  3. (17 Jan 2013) Interpreter
  4. (21 Nov 2012) Command, Redux
  5. (19 Nov 2012) Command
  6. (16 Nov 2012) Chain of responsibility
  7. (15 Nov 2012) Proxy
  8. (14 Nov 2012) Flyweight
  9. (09 Nov 2012) Façade
  10. (07 Nov 2012) Decorator
  11. (05 Nov 2012) Composite
  12. (02 Nov 2012) Bridge
  13. (01 Nov 2012) Adapter
  14. (31 Oct 2012) Singleton
  15. (29 Oct 2012) Prototype
  16. (26 Oct 2012) Factory Method
  17. (25 Oct 2012) Builder
  18. (24 Oct 2012) A modern alternative to Abstract Factory–filtered dependencies
  19. (23 Oct 2012) Abstract Factory

Comments

Rafal

I don't quite get your recommendations. You say some people use wrappers to abstract things and it's not what wrappers are meant for. But at the same time you give an example (HttpContextBase) of abstracting things through a wrapper class.

Ayende Rahien

Rafal, It depends on whatever you control the code or not.

Jeff

Spot on...very useful patter if used in the correct context and not as a means of abstraction.

Mike McG

I'm not sure that I follow your argument here. You say that it should be used only to "integrate two or more external systems/libraries" but then say that HttpContextWrapper is a good example of it. HttpContextWrapper involves only a single external library (System.Web being external to System.Web.Mvc). These two statements contradict.

I've found this pattern critically useful whenever I have a high-level interface-based design, and want to leverage third-party libraries to implement the interfaces at a later time. Those external libraries by definition do not implement my internal interfaces, requiring me to write an adapter. Thinner adapters are better, but sometimes some non-trivial shimming must be implemented to make the adaptation workable. Either way, the external dependency is fully abstracted by the interface, and the adapter is what makes this all work. It's perhaps a matter of semantics, then, that the adapter does or does not provide abstraction.

In my opinion, especially in an era of FLOSS and web service explosion, leveraging external resources without sacrificing design is critical. The adapter pattern does this and therefore is as important as ever.

Rafal

'Adapter' in the context of this post is just another name for wrapper. But imho to be called an 'adapter' the module should include a nontrivial mapping/translation logic - otherwise it's just a wrapper. And I disagree that wrappers should be used only when you don't control the code - sometimes you introduce them deliberately to reduce dependencies on external libraries by abstracting them. Example: logging library wrappers.

Ayende Rahien

Mike, There are actually two of them here, System.Web, System.Web.Abstractions and System.Web.MVC. They couldn't change System.Web, and require the extra abstraction to allow to swap things.

Comment preview

Comments have been closed on this topic.

FUTURE POSTS

  1. What is new in RavenDB 3.5–Intro - 5 hours from now
  2. Production postmortem: The case of the infected cluster - about one day from now

There are posts all the way to Jul 09, 2015

RECENT SERIES

  1. The RavenDB Comic Strip (3):
    28 May 2015 - Part III – High availability & sleeping soundly
  2. Special Offer (2):
    27 May 2015 - 29% discount for all our products
  3. RavenDB Sharding (3):
    22 May 2015 - Adding a new shard to an existing cluster, splitting the shard
  4. Challenge (45):
    28 Apr 2015 - What is the meaning of this change?
  5. Interview question (2):
    30 Mar 2015 - fix the index
View all series

Syndication

Main feed Feed Stats
Comments feed   Comments Feed Stats