Мост (шаблон проектирования)

Материал из Seo Wiki - Поисковая Оптимизация и Программирование

Перейти к: навигация, поиск

Bridge, Мостшаблон проектирования, используемый в проектировании программного обеспечения чтобы «разделять абстракцию и реализацию так, чтобы они могли изменяться независимо». Шаблон bridge (от англ. — мост) использует инкапсуляцию, агрегирование и может использовать наследование для того, чтобы разделить ответственность между классами.

Содержание

Цель

При частом изменении класса, преимущества объектно-ориентированного подхода становятся очень полезными, позволяя делать изменения в программе, обладая минимальными сведениями о реализации программы. Шаблон bridge является полезным там, где не только сам класс часто меняется, но и то, что класс делает.

Описание

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

Примеры

Пример на C#

using System;
 
namespace Bridge
{
 
  // MainApp test application
 
  class MainApp
  {
    static void Main()
    {
      Abstraction ab = new RefinedAbstraction();
 
      // Set implementation and call
      ab.Implementor = new ConcreteImplementorA();
      ab.Operation();
 
      // Change implemention and call
      ab.Implementor = new ConcreteImplementorB();
      ab.Operation();
 
      // Wait for user
      Console.Read();
    }
  }
 
  /// <summary>
  /// Abstraction - абстракция
  /// </summary>
  /// <remarks>
  /// <li>
  /// <lu>определяем интерфейс абстракции;</lu>
  /// <lu>хранит ссылку на объект <see cref="Implementor"/></lu>
  /// </li>
  /// </remarks>
  class Abstraction
  {
    protected Implementor implementor;
 
    // Property
    public Implementor Implementor
    {
      set{ implementor = value; }
    }
 
    public virtual void Operation()
    {
      implementor.Operation();
    }
  }
 
  /// <summary>
  /// Implementor - реализатор
  /// </summary>
  /// <remarks>
  /// <li>
  /// <lu>определяет интерфейс для классов реализации. Он не обязан точно
  /// соотведствовать интерфейсу класса <see cref="Abstraction"/>. На самом деле оба
  /// интерфейса могут быть совершенно различны. Обычно интерфейс класса
  /// <see cref="Implementor"/> представляет только примитивные операции, а класс
  /// <see cref="Abstraction"/> определяет операции более высокого уровня, 
  /// базирующиеся на этих примитивах;</lu>
  /// </li>
  /// </remarks>
  abstract class Implementor
  {
    public abstract void Operation();
  }
 
  /// <summary>
  /// RefinedAbstraction - уточненная абстракция
  /// </summary>
  /// <remarks>
  /// <li>
  /// <lu>расширяет интерфейс, определенный абстракцией <see cref="Abstraction"/></lu>
  /// </li>
  /// </remarks>
  class RefinedAbstraction : Abstraction
  {
    public override void Operation()
    {
      implementor.Operation();
    }
  }
 
  /// <summary>
  /// ConcreteImplementor - конкретный реализатор
  /// </summary>
  /// <remarks>
  /// <li>
  /// <lu>содержит конкретную реализацию интерфейса <see cref="Implementor"/></lu>
  /// </li>
  /// </remarks>
  class ConcreteImplementorA : Implementor
  {
    public override void Operation()
    {
      Console.WriteLine("ConcreteImplementorA Operation");
    }
  }
 
  // "ConcreteImplementorB"
 
  class ConcreteImplementorB : Implementor
  {
    public override void Operation()
    {
      Console.WriteLine("ConcreteImplementorB Operation");
    }
  }
}

Пример JavaScript

// Implementor ("интерфейс")
function Implementor() {
	this.operation = function() {};
}
 
// ConcreteImplementor (реализация Implementor)
function ConcreteImplementorA() {
	this.operation = function() {
		alert("ConcreteImplementorA.operation");
	};
}
ConcreteImplementorA.prototype = new Implementor();
ConcreteImplementorA.prototype.constructor = ConcreteImplementorA;
 
function ConcreteImplementorB() {
	this.operation = function() {
		alert("ConcreteImplementorB.operation");
	};
}
ConcreteImplementorB.prototype = new Implementor();
ConcreteImplementorB.prototype.constructor = ConcreteImplementorB;
 
// Abstraction
function Abstraction() {
	var implementor;
 
	this.getImplementor = function() {
		// доступ к implementor'у из RefinedAbstraction 
		return implementor;
	};
	this.setImplementor = function(val) {
		implementor = val;
	};
	this.operation = function() {
		implementor.operation();
	};
}
 
// RefinedAbstraction
function RefinedAbstraction() {
	var abstr = new Abstraction();
 
	this.setImplementor = function(val) {
		abstr.setImplementor(val);
	};
	this.operation = function() {
		abstr.operation();
	};
}
 
// использование:
var refAbstr = new RefinedAbstraction();
refAbstr.setImplementor( new ConcreteImplementorA() );
refAbstr.operation(); // "ConcreteImplementorA.operation"
 
refAbstr.setImplementor( new ConcreteImplementorB() );
refAbstr.operation(); // "ConcreteImplementorB.operation"

Без необходимости перегрузки методов Abstraction, можно значительно упростить RefinedAbstraction:

function RefinedAbstraction() {
	Abstraction.call(this);
}

Так же можно сохранить ссылки на перегружаемые методы сразу после инстанцирования Abstraction:

function RefinedAbstraction() {
	Abstraction.call(this);
	var abstr_setImplementor = this.setImplementor;
 
	this.setImplementor = function(val) {
		abstr_setImplementor(val);
	};
}




структурные шаблоны проектирования

адаптер | мост | компоновщик | декоратор | фасад | заместитель | приспособленец | Выделение частного класса данных

bg:Мост (шаблон)

de:Brücke (Entwurfsmuster) en:Bridge pattern es:Bridge (patrón de diseño) fr:Pont (patron de conception) it:Bridge pattern ja:Bridge パターン ko:브리지 패턴 pl:Most (wzorzec projektowy) pt:Bridge (padrão) uk:Міст (шаблон проектування) vi:Bridge pattern zh:橋接模式

Личные инструменты

Served in 0.641 secs.