Мост (Bridge) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Пример)
(Участники)
Строка 31: Строка 31:
  
 
==== Участники====
 
==== Участники====
* Abstraction - абстракция
+
* '''Abstraction''' - абстракция
 
Определяет интерфейс абстракции. Дает реализацию этого интерфейса, вызывая методы Implementorа
 
Определяет интерфейс абстракции. Дает реализацию этого интерфейса, вызывая методы Implementorа
* RefinedAbstraction - уточненная абстракция
+
* '''RefinedAbstraction''' - уточненная абстракция
 
Расширяет интерфейс абстракции. Дает реализацию новых методов как в терминах методов базового класса, так и вызывая методы Implementorа
 
Расширяет интерфейс абстракции. Дает реализацию новых методов как в терминах методов базового класса, так и вызывая методы Implementorа
* Implementor - реализатор
+
* '''Implementor''' - реализатор
 
Определяет интерфейс для классов реализации. Он не обязан следовать интерфейсу абстракции. Обычно интерфейс класса Implementor предоставляет только примитивные операции, а класс Abstraction определяет операции более высокого уровня.
 
Определяет интерфейс для классов реализации. Он не обязан следовать интерфейсу абстракции. Обычно интерфейс класса Implementor предоставляет только примитивные операции, а класс Abstraction определяет операции более высокого уровня.
* ConcreteImplementor - конкретный реализатор
+
* '''ConcreteImplementor''' - конкретный реализатор
 
Содержит реализацию интерфейса класса Implementor
 
Содержит реализацию интерфейса класса Implementor
  

Версия 09:22, 3 августа 2014

К основной странице курса

Другое название

Назначение

Позволяет менять интерфейс и реализацию независимо друг от друга.

Описание

Если для некоторой абстракции возможно несколько реализаций, то применяют наследование. Однако, такой подход плохо работает при наличии N абстракций и M реализаций: необходимо создать N*M классов, каждый из которых для i-той абстракции дает j-тую реализацию.

Например, при реализации библиотеки пользовательского интерфейса с N компонентами - наследниками класса Window - для M операционных систем потребуется полностью реализовывать N*M классов.

Паттерн Мост позволяет свести количество необходимых классов к N+M. Таким образом, при добавлении нового оконного компонента мы должны добавить один класс независимо от количества операционных систем. Аналогично при реализации всех компонент для новой операционной системы мы должны также добавить только один класс.

Основная идея паттерна Мост заключается в следующем: для базовой абстракции (в нашем примере для класса Window) имеется класс WindowImp (реализация), содержащий интерфейс примитивов рисования графических компонент. В классе Window все примитивы рисования реализуются делегированием к операциям класса WindowImp. Теперь в потомках класса Window мы реализуем рисование компонент с помощью базового набора примитивов в классе Window, а примитивы в классе WindowImp реализуются в подклассах для каждой операционной системы.

Связка классов Window - WindowImp и называется Мост.

Использование

Паттерн Мост используется когда

  • Необходимо менять реализацию во время выполнения
  • И абстракции и реализации должны расширяться новыми подклассами
  • При изменениях в реализации абстракции клиентский код, работающий с абстракцией, не должен перекомпилироваться

Реализация

Диаграмма классов для примера Window - WindowImp

BridgeWindow.png

Диаграмма классов в общем случае

BridgeCommon.png

Участники

  • Abstraction - абстракция

Определяет интерфейс абстракции. Дает реализацию этого интерфейса, вызывая методы Implementorа

  • RefinedAbstraction - уточненная абстракция

Расширяет интерфейс абстракции. Дает реализацию новых методов как в терминах методов базового класса, так и вызывая методы Implementorа

  • Implementor - реализатор

Определяет интерфейс для классов реализации. Он не обязан следовать интерфейсу абстракции. Обычно интерфейс класса Implementor предоставляет только примитивные операции, а класс Abstraction определяет операции более высокого уровня.

  • ConcreteImplementor - конкретный реализатор

Содержит реализацию интерфейса класса Implementor

Пример

class MainApp
{
    static void Main()
    {
        Abstraction ab = new RefinedAbstraction();

        ab.Implementor = new ConcreteImplementorX();
        ab.OperationA();
        ab.OperationB();

        ab.Implementor = new ConcreteImplementorY();
        ab.OperationA();
        ab.OperationB();
    }
}

class Abstraction
{
    public Implementor Implementor
    {
        get; set;
    }
    public virtual void OperationA()
    {
        Implementor.Op1();
    }
    public virtual void OperationB()
    {
        Implementor.Op2();
    }
}

abstract class Implementor
{
    public abstract void Op1();
    public abstract void Op2();
}

class RefinedAbstraction : Abstraction
{
    public override void OperationB()
    {
        OperationA();
        Implementor.Op2();
    }
}

class ConcreteImplementorX : Implementor
{
    public override void Op1()
    {
        Console.WriteLine("ConcreteImplementorX Op1");
    }
    public override void Op2()
    {
        Console.WriteLine("ConcreteImplementorX Op2");
    }
}

class ConcreteImplementorY : Implementor
{
    public override void Op1()
    {
        Console.WriteLine("ConcreteImplementorY Op1");
    }
    public override void Op2()
    {
        Console.WriteLine("ConcreteImplementorY Op2");
    }
}

Достоинства и недостатки

Варианты