Recently I was developing some unit tests that had a dependency on a third party library and I found the adapter pattern applicable. I have decided to share what motivated me to apply this pattern since it is common dilemma. In addition, I am providing some general information on the adapter pattern that I hope will be useful.
My initial need for the pattern occurred when I was using SubSonic, an open-source data access layer that uses the active record pattern. SubSonic's implementation of the active record pattern relies heavily on static methods to access data, which is not always necessary. In addition, I use RhinoMocks, an open-source unit testing framework, to help with my testing. With RhinoMocks, static methods cannot be mocked. The adapter pattern paid for itself by providing me a common interface with a third party library and encapsulating active record's static methods.
SubSonic is a powerful option for data access and I recommend trying it out. In my situation, SubSonic and RhinoMocks fail to play nicely together due to static "Fetch" methods. In my application, I can retrieve all of my products, or a single product, using SubSonic like the following code below.
1: IDataReader dataReader = Product.FetchAll();
2: Product product = Product.FetchByID(1);
In my service layer, I call the static method "FetchAll," using something similar to what is shown above. If I want to write a unit test for this class, I need to write more code to get this static dependency resolved. I could use TypeMock to mock this static method, but I choose to use RhinoMocks, and since RhinoMocks cannot mock static methods, I need to consider refactoring. I am using a third party library, and while I do have the source code for it, implementing the adapter pattern is easier than rewriting SubSonic for what I need.
Adapter pattern to the rescue
The adapter pattern converts the interface of a class into an interface that clients expect (dofactory.com). The client expects what is defined by the target interface. The adapter implements the target interface and is composed with the adaptee. The adaptee receives receives all the requests from the adapter. Below is a UML diagram depicting the relationship among the objects.

The adapter pattern is useful in situations where:
- Two or more classes are doing similar things but have different interfaces
- You are using a third party API or framework that many clients already use
- You are using a third party API or framework and you do not have access to modify its source code
- You are using static methods that need to be mocked for unit testing using RhinoMocks
In my situation, SubSonic provides data access functionality that I need to encapsulate behind an interface that my clients expect. This will in turn make it easier for me to allow other data providers to participate in the future. Before refactoring, my service class's GetAllProducts() method calls the static method Product.FetchAll(). After refactoring, I move the Product.FetchAll functionality into its own class, ProductDAO. I now pass a reference to ProductDAO into my service layer class. This I can easily mock with RhinoMocks.
1: public class ProductService
2: {
3: private IDomainDAO dataAccess = null;
4:
5: public ProductService(IDomainDAO dataAccess)
6: {
7: this.dataAccess = dataAccess;
8: }
9:
10: public IList<ProductDTO> GetAllProducts()
11: {
12: IDataReader dataReader = dataAccess.FetchAllByName();
13: IList<ProductDTO> productList = new List<ProductDTO>();
14:
15: while (dataReader.Read())
16: {
17: int id = int.Parse(dataReader["ProductID"].ToString());
18: string name = dataReader["ProductName"].ToString();
19: productList.Add(new ProductDTO(id, name));
20: }
21:
22: return productList;
23: }
24: }
My service class, ProductService, now only references an interface called IDomainDAO, which is my "Target." My "Adapter," ProductDAO, implements that interface. ProductDAO has a reference to the "Adaptee," SubSonicProductDAO. My ProductDAO delegates its requests to the adaptee.
1: public interface IDomainDAO
2: {
3: IDataReader FetchAllByName();
4: }
5:
6: public class ProductDAO : IDomainDAO
7: {
8: SubSonicProductDAO adaptee = new SubSonicProductDAO();
9:
10: public IDataReader FetchAllByName()
11: {
12: adaptee.FetchAll();
13: }
14: }
15:
16: public class SubSonicProductDAO
17: {
18: public IDataReader FetchAll()
19: {
20: return Product.FetchAll();
21: }
22: }
In the example above, I implemented the adapter pattern as outlined in the UML diagram. I did not actually need to create the adaptee since I am using static methods. I could have just had my adaptor's FetchAllByName() function call Product.FetchAll(). I wanted to stick to the pattern.
The unit test exercising my ProductService's GetAllProducts() method looks like the following. With RhinoMocks, I can mock my target, IDomainDAO. At some point, a unit test will be needed that will test that static method. It cannot avoid being tested forever. I would feel comfortable testing this in a separate integration test project so as not to violate the rules of unit testing.
1: [Test]
2: public void GetAllProducts_ShouldReturn_ListOfProductDTOs()
3: {
4: using (mocks.Record())
5: {
6: IDomainDAO dataAccess = mocks.DynamicMock<IDomainDAO>();
7: dataReader = mocks.DynamicMock<IDataReader>();
8:
9: Expect.Call(dataAccess.FetchAllByName()).Return(dataReader);
10: Expect.Call(dataReader.Read()).Return(true);
11:
12: Expect.Call(dataReader["ProductID"]).Return(1);
13: Expect.Call(dataReader["ProductName"]).Return("My Product");
14:
15: Expect.Call(dataReader.Read()).Return(false);
16: }
17:
18: using (mocks.Playback())
19: {
20: IList<ProductDTO> productList = new List<ProductDTO>();
21:
22: Assert.AreEqual(0, productList.Count);
23:
24: productList = service.GetAllProducts();
25:
26: Assert.AreEqual(1, productList.Count);
27: }
28: }
Code Smells Indicative of the Adapter Pattern (thanks to Industrial Logic)
Alternative Classes with Different Interfaces
Occurs when the interfaces of two classes are different and yet the classes are quite similar. If you can find the similarities between
the two classes, you can often refactor the classes to make them share a common interface.
Duplicated Code Smell
Duplicated code is the most pervasive and pungent smell in software. It tends to be either explicit or subtle. Explicit duplication exists in identical code, while subtle duplication exists in structures or processing steps that are outwardly different, yet essentially the same.
Oddball Solution Smell
When a problem is solved one way throughout a system and the same problem is solved another way in the same system, one of the solutions is the oddball or inconsistent solution. The presence of this smell usually indicates subtly duplicated code.
The adapter pattern often works in conjunction with the facade pattern. While the adapter adapts objects, the facade is used to adapt systems. I will not go into more detail for the facade pattern. Perhaps it will become a separate post.
In my situation described above, I really needed the adapter pattern to help me bypass the issue with RhinoMocks not allowing me to mock static functions. If you have static functions in your code and they are proving difficult to test, determine if they are necessary and/or refactor them.