BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Design Patterns
.NET 1.1+

Adapter Design Pattern

The adapter pattern is a design pattern that is used to allow two incompatible types to communicate. Where one class relies upon a specific interface that is not implemented by another class, the adapter acts as a translator between the two types.

Example Adapter

To demonstrate further, we will now create an example of the adapter. This example will perform the translation of employee details between the personnel system and the intranet telephone list described earlier in this article. As the implications of such a system could be very large, we will create a very simplified, and rather contrived, example.

Let's start by creating the intranet telephone list class. This class will perform a request for employee details by calling the GetPhoneList method on an object that implements the IIntranetPhoneList interface. This object will be provided during instantiation. The method expects that the phone list will be returned in a comma-separated format containing a name, job title and telephone number. Employee records will be separated by a new line character. For simplicity, this string is outputted to the console by the ShowPhoneList method.

public class Intranet
{
    private IIntranetPhoneList _phoneListSource;

    public Intranet(IIntranetPhoneList phoneListSource)
    {
        _phoneListSource = phoneListSource;
    }

    public void ShowPhoneList()
    {
        string phoneNumbers = _phoneListSource.GetPhoneList();

        Console.WriteLine(phoneNumbers);
    }
}


public interface IIntranetPhoneList
{
    string GetPhoneList();
}

Next we will examine the Personnel system class. This class returns the required data for the phone list but in a different format. Each employee is represented by an array containing three strings for the telephone number, name and job title. To return multiple employees, an array of arrays is generated.

NB: This awkward return value is included here because it is reasonably simple to convert to the target string. This type of return value is not advisable in a production system.

public class PersonnelSystem
{
    public string[][] GetEmployees()
    {
        string[][] employees = new string[4][];

        employees[0] = new string[] { "1201", "Jim", "Team Leader" };
        employees[1] = new string[] { "1202", "Bob", "Developer" };
        employees[2] = new string[] { "1203", "Sue", "Developer" };
        employees[3] = new string[] { "1204", "Dan", "Tester" };

        return employees;
    }
}

As the two types are incompatible, we can create an adapter to undertake the required translation. The adapter performs two tasks in this case. Firstly a call to GetPhoneList is rerouted to GetEmployees. Secondly, the arrays are converted to the desired comma-separated format before they are returned to the Intranet class.

public class PhoneListAdapter : IIntranetPhoneList
{
    private PersonnelSystem _personnel;

    public PhoneListAdapter(PersonnelSystem personnel)
    {
        _personnel = personnel;
    }

    public string GetPhoneList()
    {
        string[][] employees = _personnel.GetEmployees();
        StringBuilder phoneList = new StringBuilder();

        foreach (string[] employee in employees)
        {
            phoneList.Append(employee[1]);
            phoneList.Append(',');
            phoneList.Append(employee[2]);
            phoneList.Append(',');
            phoneList.Append(employee[0]);
            phoneList.Append('\n');
        }

        return phoneList.ToString();
    }
}

Testing the Adapter

To test the adapter example we can use the Main method of a console application. As you can see, we first create a PersonnelSystem object. We then create a new adapter that holds a reference to the PersonnelSystem object. Finally, we can instantiate our Intranet object, passing the adapter to use as its source of telephone list information. The call to ShowPhoneList is intercepted by the adapter so that the data can be retrieved from the incompatible PersonnelSystem object and correctly formatted for output.

static void Main(string[] args)
{
    PersonnelSystem personnel = new PersonnelSystem();
    PhoneListAdapter adapter = new PhoneListAdapter(personnel);
    Intranet intranet = new Intranet(adapter);
    intranet.ShowPhoneList();
}

/* OUTPUT

Jim,Team Leader,1201
Bob,Developer,1202
Sue,Developer,1203
Dan,Tester,1204

*/
2 December 2008