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

Мост (Bridge)

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

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

Рис. 5 демонстрирует упрощенную диаграмму дизайна шаблона Мост. На диаграмме показан только один абстрактный тип. Этот тип агрегирует некий конкретный объект-мост, которому делегируется выполнение требуемых операций.

Рис. 5. UML-диаграмма шаблона Мост.

При реализации шаблона инстанциирование конкретного моста обычно происходит в конструкторе. Далее приведён пример кода, приблизительно соответствующий описанной выше иллюстрации применения шаблона Мост.

public class Sensor

{

private readonly Bridge bridge;

public Sensor(Bridge bridge)

{

this.bridge = bridge;

}

public double GetValue()

{

return bridge.GetSensorValue();

}

}

public interface Bridge

{

double GetSensorValue();

}

public class ImplementationA : Bridge

{

public double GetSensorValue()

{

System.Console.WriteLine("Implementation A");

return -1;

}

}

public class ImplementationB : Bridge

{

public double GetSensorValue()

{

System.Console.WriteLine("Implementation B");

return 0;

}

}

public class BridgeExample

{

private static void Main()

{

var sensor = new Sensor(new ImplementationA());

sensor.GetValue();

}

}

3.4. Структурные шаблоны: компоновщик и приспособленец Компоновщик (Composite)

Компоновщик – один из простейших структурных шаблонов. Его задача – агрегировать объекты, обладающие общим интерфейсом, и обеспечить выполнение операций этого интерфейса над всеми агрегируемыми объектами.

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

Дизайн шаблона Компоновщика показан на рис. 6. То, что и компоновщик, и отдельный объект реализуют один и тот же интерфейс, удобно с точки зрения клиента, который не видит разницы между ними в плане функциональности. Обычно компоновщика снабжают методами добавления, удаления, редактирования и поиска отдельных агрегируемых компонент.

Рис. 6. Дизайн шаблона Компоновщик.

Рассмотрим пример реализации шаблона Компоновщик. Код примера позволяет организовывать вложенность компонентов произвольной глубины, а также реализует типичные операции с компонентами.

using System;

using System.Collections.Generic;

public interface IComponent<T>

{

T Item { get; set; }

void Add(IComponent<T> c);

IComponent<T> Remove(T s);

IComponent<T> Find(T s);

}

// Отдельный компонент

public class Component<T> : IComponent<T>

{

public T Item { get; set; }

public Component(T item)

{

Item = item;

}

public void Add(IComponent<T> c)

{

Console.WriteLine("Cannot add to an item");

}

public IComponent<T> Remove(T s)

{

Console.WriteLine("Cannot remove directly");

return this;

}

public IComponent<T> Find(T s)

{

return s.Equals(Item) ? this : null;

}

}

// Компоновщик

public class Composite<T> : IComponent<T>

{

private readonly List<IComponent<T>> list;

public T Item { get; set; }

public Composite(T item)

{

Item = item;

list = new List<IComponent<T>>();

}

public void Add(IComponent<T> c)

{

list.Add(c);

}

public IComponent<T> Remove(T s)

{

var p = Find(s);

if (p != null)

{

list.Remove(p);

}

return this;

}

public IComponent<T> Find(T s)

{

if (Item.Equals(s))

{

return this;

}

IComponent<T> found = null;

foreach (var c in list)

{

found = c.Find(s);

if (found != null)

{

break;

}

}

return found;

}

}