Адаптер (Adapter)

Шаблон Адаптер нужен для обеспечения коллективной работы классов, которые изначально не были созданы для совместного использования. Такие ситуации часто возникают, когда идёт работа со сторонними библиотеками кода. Нередко их интерфейс не отвечает требованиям клиента[3], но изменить библиотеку нет возможности. Следовательно, появляется задача адаптации библиотеки для клиента.

Два основных варианта дизайна шаблона Адаптер показаны на рис. 1. Класс Client работает в соответствии с требованиями своей предметной области, эти требования отражены в интерфейсе ITarget. Адаптируемый класс Adaptee обладает нужной функциональностью, но неподходящим интерфейсом. Класс Adapter реализует интерфейс ITarget и перенаправляет вызовы от Client к Adaptee, изменяя при необходимости параметры и возвращаемые значения. В случае адаптера класса Adapter одновременно реализует интерфейс ITarget и наследуется от класса Adaptee. Альтернативой наследованию может стать агрегация объекта Adaptee, что соответствует адаптеру объекта. При наследовании проще переопределить поведение адаптируемого класса, а при агрегации – легче добавить к адаптируемому классу новое поведение.

Рис. 1. Дизайн адаптера класса (вверху) и адаптера объекта (внизу).

Рассмотрим пример реализации адаптера объекта. Пусть в приложении необходимо воспроизводить звуковые файлы в формате wav. Интерфейс IAudioPlayer содержит описание функций простого медиаплеера, осуществляющего загрузку и воспроизведение аудиофайла.

public interface IAudioPlayer

{

// загрузка аудиофайла

void Load(string file);

// воспроизведение аудиофайла

void Play();

}

При реализации обратим внимание на тот факт, что платформа.NET уже содержит класс System.Media.SoundPlayer, предоставляющий подобные возможности. Однако данный класс не поддерживает заданный интерфейс. Поэтому воспользуемся шаблоном Адаптер.

public class SoundPlayerAdapter: IAudioPlayer

{

// адаптируемый объект

private readonly SoundPlayer _player = new SoundPlayer();

public void Load(string file)

{

_player.SoundLocation = file;

_player.Load();

}

public void Play()

{

_player.Play();

}

}

В отличие от явного использования класса SoundPlayer, применённый подход обеспечил независимость кода клиента от конкретной реализации медиаплеера. Например, в дальнейшем можно легко заменить SoundPlayerAdapter на другой класс для поддержки файлов иного формата.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: