http://www.dofactory.com/Patterns/PatternBridge.aspx
위에서 퍼온 글입니다.(약간 다른 내용이 포함되어있다)
definition
브릿지 패턴은 소프트웨어 공학에서 사용되는 디자인 패턴인데, 이는 "구현(implementation)으로부터 추상(abstraction) 레이어를 분리하여 이 둘이 서로 독립적으로 변화할 수 있도록 한다."
브릿지는 캡슐화(encapsulation), 집합(aggregation)을 사용하고 또한 다른 클래스들로 책임을 분리시키기 위해 상속(inheritance)를 사용할 수 있다.
어떤 클래스가 자주 바뀐다면(varies), 객체 지향 프로그래밍의 특징들은 아주 유용해질 수 있다. 왜냐하면 프로그램 코드를 수정하는데 프로그램에 대해 최소한만 알고도 쉽게 수정할 수 있기 때문이다. 브릿지 패턴은 어떤 클래스와 그 클래스가 하는 일이 자주 변화할 때 유용하게 사용될 수 있다. 여기에서 어떤 클래스는 구현(implementation)이라 생각할 수 있고, 그 클래스가 할 수 있는 일은 추상(abstraction)으로 생각할 수 있다. 브릿지 패턴은 추상화(abstraction)의 두 계층(layer)로 생각할 수도 있다.
브릿지 패턴은 종종 어댑터 패턴과 혼동될 수 있다. 사실, 브릿지 패턴은 종종 클래스 어댑터 패턴을 사용해서 구현되기도 한다.
변종(Variant) : 추상(abstraction)이 사용되는 시점까지 구현의 존재를 미룸으로써 구현을 더욱 갈라놓을 수 있다.(정확히 이해는 안되지만 구현 객체를 최대한 늦게 생성함으로써 구현과 추상의 관계를 더욱 약하게 할 수 있다는 말인것 같네요;.
원문 : The implementation can be decoupled even more by deferring the presence of the implementation to the point where the abstraction is utilized.)
UML class diagram

sample code in C#
이코드는 구현체를 인터페이스로 분리하는 Bridge Pattern 을 설명하는 구조적인 코드입니다.
// Bridge pattern -- Structural example |
using System;
namespace DoFactory.GangOfFour.Bridge.Structural { /// <summary> /// MainApp startup class for Structural /// Bridge Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> 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.ReadKey(); } }
/// <summary> /// The 'Abstraction' class /// </summary> class Abstraction { protected Implementor implementor;
// Property public Implementor Implementor { set { implementor = value; } }
public virtual void Operation() { implementor.Operation(); } }
/// <summary> /// The 'Implementor' abstract class /// </summary> abstract class Implementor { public abstract void Operation(); }
/// <summary> /// The 'RefinedAbstraction' class /// </summary> class RefinedAbstraction : Abstraction { public override void Operation() { implementor.Operation(); } }
/// <summary> /// The 'ConcreteImplementorA' class /// </summary> class ConcreteImplementorA : Implementor { public override void Operation() { Console.WriteLine("ConcreteImplementorA Operation"); } }
/// <summary> /// The 'ConcreteImplementorB' class /// </summary> class ConcreteImplementorB : Implementor { public override void Operation() { Console.WriteLine("ConcreteImplementorB Operation"); } } } |
Output ConcreteImplementorA Operation ConcreteImplementorB Operation |
BusinessObject추상은 DataObject구현으로부터 분리되어있는 실제적인 Bridge pattern을 설명하고 있다.
// Bridge pattern -- Real World example |
using System; using System.Collections.Generic;
namespace DoFactory.GangOfFour.Bridge.RealWorld { /// <summary> /// MainApp startup class for Real-World /// Bridge Design Pattern. /// </summary> class MainApp { /// <summary> /// Entry point into console application. /// </summary> static void Main() { // Create RefinedAbstraction Customers customers = new Customers("Chicago");
// Set ConcreteImplementor customers.Data = new CustomersData();
// Exercise the bridge customers.Show(); customers.Next(); customers.Show(); customers.Next(); customers.Show(); customers.Add("Henry Velasquez");
customers.ShowAll();
// Wait for user Console.ReadKey(); } }
/// <summary> /// The 'Abstraction' class /// </summary> class CustomersBase { private DataObject _dataObject; protected string group;
public CustomersBase(string group) { this.group = group; }
// Property public DataObject Data { set { _dataObject = value; } get { return _dataObject; } }
public virtual void Next() { _dataObject.NextRecord(); }
public virtual void Prior() { _dataObject.PriorRecord(); }
public virtual void Add(string customer) { _dataObject.AddRecord(customer); }
public virtual void Delete(string customer) { _dataObject.DeleteRecord(customer); }
public virtual void Show() { _dataObject.ShowRecord(); }
public virtual void ShowAll() { Console.WriteLine("Customer Group: " + group); _dataObject.ShowAllRecords(); } }
/// <summary> /// The 'RefinedAbstraction' class /// </summary> class Customers : CustomersBase { // Constructor public Customers(string group) : base(group) { }
public override void ShowAll() { // Add separator lines Console.WriteLine(); Console.WriteLine("------------------------"); base.ShowAll(); Console.WriteLine("------------------------"); } }
/// <summary> /// The 'Implementor' abstract class /// </summary> abstract class DataObject { public abstract void NextRecord(); public abstract void PriorRecord(); public abstract void AddRecord(string name); public abstract void DeleteRecord(string name); public abstract void ShowRecord(); public abstract void ShowAllRecords(); }
/// <summary> /// The 'ConcreteImplementor' class /// </summary> class CustomersData : DataObject { private List<string> _customers = new List<string>(); private int _current = 0;
public CustomersData() { // Loaded from a database _customers.Add("Jim Jones"); _customers.Add("Samual Jackson"); _customers.Add("Allen Good"); _customers.Add("Ann Stills"); _customers.Add("Lisa Giolani"); }
public override void NextRecord() { if (_current <= _customers.Count - 1) { _current++; } }
public override void PriorRecord() { if (_current > 0) { _current--; } }
public override void AddRecord(string customer) { _customers.Add(customer); }
public override void DeleteRecord(string customer) { _customers.Remove(customer); }
public override void ShowRecord() { Console.WriteLine(_customers[_current]); }
public override void ShowAllRecords() { foreach (string customer in _customers) { Console.WriteLine(" " + customer); } } } } |
Output Jim Jones Samual Jackson Allen Good ------------------------ Customer Group: Chicago Jim Jones Samual Jackson Allen Good Ann Stills Lisa Giolani Henry Velasquez ------------------------ |