Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шаблоны и архитектура программ.doc
Скачиваний:
12
Добавлен:
04.05.2019
Размер:
558.08 Кб
Скачать

3.5. Структурные шаблоны: адаптер и фасад Адаптер (Adapter)

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

Дизайн шаблона Адаптер показан на рис. 8.

Рис. 8. Дизайн шаблона Адаптер.

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

Существует несколько разновидностей адаптеров. На рис. 8 показан адаптер класса, поскольку он одновременно реализует интерфейс и наследует от адаптируемого класса Adaptee. Альтернативой наследованию может стать агрегация объекта типа Adaptee. В этом случае получится адаптер объекта. Разница в этих двух способах в том, что при наследовании легче переопределить поведение Adaptee, а при агрегации – добавить к Adaptee поведение.

Рассмотрим простой пример применения шаблона Адаптер. Допустим данные (числа) хранятся в некотором компоненте с высокой точностью, а клиент умеет оперировать ими только как с целыми числами. Поэтому методы интерфейса, которым пользуется клиент, содержат параметры целого типа, а методы компонента – параметры вещественного типа.

using System;

public interface ITarget

{

string Request(int i);

}

public class Adaptee

{

public double SpecificRequest(double a, double b)

{

return a / b;

}

}

public class Adapter : Adaptee, ITarget

{

public string Request(int i)

{

return "Rough: " + (int)Math.Round(SpecificRequest(i, 3));

}

}

public class Client

{

private static void Main()

{

var adaptee = new Adaptee();

Console.Write("Before the new standard: ");

Console.WriteLine(adaptee.SpecificRequest(5, 3));

ITarget adapter = new Adapter();

Console.Write("Moving to the new standard: ");

Console.WriteLine(adapter.Request(5));

}

}

Особенность адаптеров в том, что они могут добавлять дополнительное поведение к тому поведению, что специфицируется в ITarget и в Adaptee. Другими словами, адаптеры могут быть прозрачными для клиента и непрозрачными. В примере кода показан последний случай, где Adapter добавляет "Rough:". Эта добавка показывает, что вызов Request() был адаптирован (изменен) перед тем, как был вызван метод SpecificRequest().

Фасад (Façade)

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

В качестве иллюстрации использования шаблона Фасад приведём работу с классами подсистемы отправки почтовых сообщений. Письмо, адресат, тело письма, почтовый сервер, присоединённые к письму файлы – все это является отдельным объектами специальных классов. Без применения фасада клиент должен взаимодействовать со всем перечисленным набором объектов, используя их свойства и методы. Фасад берет работу по взаимодействию на себя – теперь клиент использует только объект-фасад, который делегирует работу нужным подсистемам.

Сокрытие деталей – это ключевая концепция программирования. Шаблон Фасад отличает от таких шаблонов, как Декоратор или Адаптер, тот факт, что интерфейс, который строится над подсистемой, может быть абсолютно любым, он не должен удовлетворять заданным заранее правилам. Допускается существование даже нескольких фасадов для одного набора подсистем.

Детали реализации шаблона Фасад не представляют трудностей. Из возможных вариантов отметим прозрачные фасады (в этом случае компоненты подсистемы могут быть доступны и через фасад, и в обход его) и статические фасады (фасад является статическим классом – скрываемые объекты не агрегируются, а создаются в методах фасада по необходимости).

Рис. 9. Дизайн шаблона проектирования Фасад.