The Adapter Pattern, A Code Diplomat

June 11th 2009 | David Cooksey
The Adapter Pattern, A Code Diplomat
The adapter pattern is useful in resolving code disputes between two classes that cannot be changed. It encapsulates all communication between the two classes—much like the way a good diplomat translates his country’s requests into the most advantageous format for the country he serves in.
Let’s look at a practical example.
Imagine you are writing software to manage a set of bank accounts. Your program accesses the bank accounts through an API published by the bank, called EasyBank. Your project has been in development for a few months, and a considerable amount of work has been done. You’ve created a class structure which includes an Account class that holds local copies of variables like the balance; last 10 debits/credits; the date the account was opened, etc. This class is wired up to various web pages that allow the user to view reports and change their preferences. On the back end, the Account class calls an EasyBankInterface class that encapsulates the various method calls to the EasyBank API for fetching and modifying data.
So far, so good.
Then your boss walks into your office and tells you that the higher-ups have purchased a commercial package that wraps the EasyBank API, and they want you to use it.
Uh oh.
After failing to successfully argue that the project doesn’t need a commercial API, you take a look at the code. It’s dramatically different. The Account class looks something like this:
Account {
String AccountName()
Decimal GetAccountBalance()
}
The commercial API is based on a single GetAccountInfo() function that populates a CommercialAccount class and returns it. All of their other functions are method calls off the CommercialAccount class.
You don’t want to rework everything in your code to use CommercialAccount instead of Account. Besides, Account stores some custom fields that are used in your reports.
This is where the adapter pattern comes in.You simply create an AccountAdapter class that contains a CommercialAccount instance and expose any methods you need on the AccountAdapter. See pseudocode below.
AccountAdapter : IAccount {
Private CommercialAccount commercialAccount;
Public AccountAdapter() {
commercialAccount = CommercialAPI.GetAccountInfo();
}
Public string AccountName() {
Return commercialAccount.Name;
}
Public decimal GetAccountBalance() {
Return commercialAccount.Balance;
}
In this example the AccountAdapter implements the IAccount interface. If your code is designed in such a way that IAccount is used everywhere, the AccountAdapter can be dropped into every pre-existing method call and very little code needs to be changed. If the IAccount is created in a single place in code, the entire adapter can be swapped out system-wide with a single code change in a single file.
This resolves a number of issues.
- All code that deals with the Commercial API is in a single place, so it is easy to maintain.
- If your company changes its mind, you can just write another adapter, or go back to your earlier implementation with ease.
- It cleanly separates code that you can’t change (API-specific code) from code related to your own internal reporting that will change in line with your company’s business needs.
The adapter pattern diplomatically resolves the conflict between the existing codebase and the new API by reducing changes to the existing infrastructure as much as possible. Like a true diplomat, it treats both sides with respect and handles conflicts between them internally to keep arguments to a minimum. What horror stories do you have related to changing requirements? Could the Adapter pattern have helped you?
Comments
One Response to “The Adapter Pattern, A Code Diplomat”
Leave a Reply

[...] Read David Cooksey’s The Adapter Pattern, A Code Diplomat [...]