Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Design

The Adapter Pattern


Conclusion

The Adapter pattern implementation I present here allows for far more flexibility than an equivalent, purely object-oriented implementation. With the proper use of compile-time meta-functions that describe certain traits of adapted types, traits classes to encapsulate those traits, an Adapter base class that defines and enforces an interface with an interface contract and derived classes generated according to the adapted types, we can successfully integrate unit-testable software in an application that has become too cohesive to unit-test, and is not coherent enough to allow for "normal" assumptions about the functioning of the code to be made.

Within the context this solution was found in, the solution is superior to both the object-oriented approach to the Adapter pattern and to a C++ Veneer implementation, which has some, but not all, of the advantages of the solution presented here.

The Task class, described above, is now a simple matter of writing a few of these adapters and the glue to make them stick together.

Notes

[1] The problem, as presented here, is a bit simplified: The actual problem I had to solve had four objects and three types which needed to be passed to the task, each of which could have different types.

[2] See C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond by David Abrahams and Aleksey Gurtovoy for more information.

[3] Both GCC-3.4.4 and MSVC8 perform this optimization.

[4] This is basically the way virtual function calls work, so a way of implementing an abstract interface would be doing the same thing the compiler does: creating a table of "virtual" functions and calling them according to the one that was asked for. Due to C++'s type-safety and a host of conceptual design problems, this is not the way we'll go, though.

[5] For instance, when using a common base class to determine an interface, all derived classes have to implement the base class' interface exactly as presented by the base class, whereas when using a traits class, the exact implementation and signature of the implementation is left to the implementer, and the traits class itself can simply serve as glue-code.

[6] Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides.

[7] A Veneer class is much like a classic Adapter in the sense that it also derives from the adaptee and implements a unified interface, and also has the advantage of the Adapter pattern as implemented here. The major difference, though, is that to use Veneers efficiently, you still have to know aforehand what you will be adapting, or fall back to using traits in the same way we d here. Using traits within a Veneer gets a bit more complicated, though, as you're no longer working on a separate class instance. Also, the adapters presented here have a base class that is not a template class and can therefore be stored without knowing the type of the adaptee -- something that can only be accomplished with Veneers when using multiple inheritance, which is something we would like to avoid for now. Veneers are still very interesting in other cases, though, and should definitely not be thrown out of your toolbox because you have this shiny new tool to work with!

[8] As you'll remember, the final application is a bowl of spaghetti of which you can't really expect any coherent behavior. Implementing and enforcing an interface contract top check whether what assumptions you have about its behavior is really what actually happens can save you a lot of trouble in the long run, as it will help pinpoint the location of any bugs within the application, rather than within your adapter.

The Source Code

The source code of every example above is available from from Dr. Dobb's andfrom me.

Only an MSVC8 solution file with its set of project files is provided for compilation, but it should be pretty straightforward to make a little Make file to compile on some other system, and I'll be happy to provide a GNU Makefile for such a purpose.


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.