Design
상속은 각기 다른 추상화의 구현에 대하여 일반적인 방법이다. 그렇지만, 구현은 추상화의 영역에 제한이 되게 되며, 추상화의 의존적인 상태에서의 변경은 제한적이 된다. Bridge pattern은 하나 이상의 추상화에 대한 상속을 통해 이미 구버젼의 추상화가 되어 있는 상황에서 추상화에 상속을 하는 것이다. 같은 추상화에서의 각각의 상속을 통해 추상화의 범위를 넓히는 것이 가능하다.
구현에 대한 동작을 Bridge에 위임하고, 동작에 대한 것을 따로 나누어주는 것으로서 구현하게 되는데, Bridge를 개선하는 것으로 전체 Class의 변경 없이 구현이 가능해진다.
using System;
namespace BridgePattern
{
public interface IBridge
{
void Add(string message);
void Add(string friend, string message);
void Poke(string who);
}
/// <summary>
/// Bridge에 의하여 구현되어진 Class
/// 구현에 의한 추상화만을 가지고 있고, 실질적인 동작은 Bridge에서 이루어지게 된다.
/// 같은 추상화에서 다른 동작을 행할때, Bridge를 변경시켜서 가능해진다.
/// </summary>
class Portal
{
readonly IBridge bridge;
public Portal(IBridge bridge)
{
this.bridge = bridge;
}
public void Add(string message)
{
bridge.Add(message);
}
public void Add(string friend, string message)
{
bridge.Add(friend, message);
}
public void Poke(string who)
{
bridge.Poke(who);
}
}
/// <summary>
/// Proxy에 의해서 보호받는 Class
/// </summary>
class Subject
{
public string SubjectName { get; set; }
public void DisplayName()
{
Console.WriteLine(SubjectName);
}
}
/// <summary>
/// Proxy
/// </summary>
class MySubject
{
private Subject subject;
public void Authritize(string password)
{
subject = new Subject();
}
public void DisplayName()
{
if ( subject == null )
{
Console.WriteLine("Subject is null");
}
else
{
subject.DisplayName();
}
}
}
/// <summary>
/// Bridge Pattern으로 만들어진 Class
/// 실질적인 동작이 이루어지는 Class
/// </summary>
public class MyBook : IBridge
{
public string Name { get; set; }
private MySubject mySubject;
private static int users;
public MyBook(string name, string password)
{
mySubject = new MySubject();
Name = name;
users++;
mySubject.Authritize(password);
}
#region IBridge Members
public void Add(string message)
{
mySubject.DisplayName();
Console.WriteLine(message);
}
public void Add(string friend, string message)
{
mySubject.DisplayName();
Console.WriteLine(string.Format("{0} : {1}", friend, message));
}
public void Poke(string who)
{
mySubject.DisplayName();
Console.WriteLine(string.Format("{0}", who));
}
#endregion
}
/// <summary>
/// C# 3.0 Extension : Class Extension, Bridge pattern에서 Bridge의 확장에 유용하게 사용할 수 있다.
/// </summary>
static class OpenBookExtensions
{
public static void SuperPoke(this Portal me, string who, string message)
{
me.Add(who, message);
}
}
class BridgePattern
{
public static void Main(string[] args)
{
Portal me = new Portal(new MyBook("Judith", "password"));
me.Add("Hello world");
me.Add("Today I worked 18 hours");
Portal tom = new Portal(new MyBook("Tom", "password2"));
tom.Poke("Judith-1");
tom.SuperPoke("Judith-1", "hugged");
tom.Add("Judith-1", "Poor you");
tom.Add("Hey, I'm on OpenBook - it's cool!");
}
}
}
Use
Bridge Pattern은 매우 간단하지만, 매우 강력한 Pattern이 된다. 하나의 구현에서 다른 구현을 이루고, 같은 추상화를 통해서 초기 디자인을 고려할 수 있기 때문이다. 잘 알려진 Bridge pattern은 Graphics에서 주로 사용된다. 각기 다른 Graphic 환경에서 다른 방법으로의 Display는 하나의 Display에 대한 추상화에서 각기 다른 Bridge를 통해서 Graphics를 구현하는 것이 가능하다.
You can:
Operation에 대한 구현을 언제나 알 필요가 없는 상태에서 Operation을 정의할 수 있다.
You want to:
- Client로부터 구현을 완벽하게 감출수 있다. (하나의 추상화에서 각기 다른 구현이 가능)
- 추상화와 구현의 binding을 피할수 있다.
- 추상화의 변경 없이, 구현을 변경하는 것이 가능하다.
- 실행시에 각기 다른 Part와 연결이 가능하다.