오늘 주제는 오늘도 역시 특별하게 생각나는 것은 없어서 Design Patterns 중 하나를 작성해보려고 한다.
이번 패턴은 구조 패턴에서 Bridge Pattern을 자세하게 알아보자.
Bridge Pattern은 객체의 기능 계층과 구현 계층을 분리하여 서로 독립적으로 확장할 수 있도록 도와주는 구조적 디자인 패턴이다.
이 패턴은 두 가지 주요 구성 요소로 나뉘는데 추상화와 구현체이다.
기능을 추상화 하여 인터페이스를 구성하고 정의한 기능 실제로 구현하여 사용한다.
코드 구현 예제를 보면 단순한 구조로 사용 할 수 있다.
using System;
namespace BridgePattern
{
// 구현체(Implementor) 인터페이스
public interface IDevice
{
void TurnOn();
void TurnOff();
void SetVolume(int volume);
}
// 구체적인 구현체 1
public class SamsungTV : IDevice
{
public void TurnOn() => Console.WriteLine("Samsung TV is turned on.");
public void TurnOff() => Console.WriteLine("Samsung TV is turned off.");
public void SetVolume(int volume) => Console.WriteLine($"Samsung TV volume set to {volume}.");
}
// 구체적인 구현체 2
public class LGTV : IDevice
{
public void TurnOn() => Console.WriteLine("LG TV is turned on.");
public void TurnOff() => Console.WriteLine("LG TV is turned off.");
public void SetVolume(int volume) => Console.WriteLine($"LG TV volume set to {volume}.");
}
// 추상화(Abstraction) 클래스
public abstract class RemoteControl
{
protected IDevice device;
protected RemoteControl(IDevice device)
{
this.device = device;
}
public abstract void PowerOn();
public abstract void PowerOff();
public abstract void SetVolume(int volume);
}
// 구체적인 추상화 1
public class BasicRemoteControl : RemoteControl
{
public BasicRemoteControl(IDevice device) : base(device) {}
public override void PowerOn() => device.TurnOn();
public override void PowerOff() => device.TurnOff();
public override void SetVolume(int volume) => device.SetVolume(volume);
}
// 구체적인 추상화 2
public class AdvancedRemoteControl : RemoteControl
{
public AdvancedRemoteControl(IDevice device) : base(device) {}
public override void PowerOn()
{
Console.WriteLine("Advanced Powering On...");
device.TurnOn();
}
public override void PowerOff()
{
Console.WriteLine("Advanced Powering Off...");
device.TurnOff();
}
public override void SetVolume(int volume)
{
Console.WriteLine("Advanced Setting Volume...");
device.SetVolume(volume);
}
public void Mute()
{
Console.WriteLine("Muting the device.");
device.SetVolume(0);
}
}
class Program
{
static void Main()
{
IDevice samsungTV = new SamsungTV();
IDevice lgTV = new LGTV();
RemoteControl basicRemote = new BasicRemoteControl(samsungTV);
RemoteControl advancedRemote = new AdvancedRemoteControl(lgTV);
basicRemote.PowerOn();
basicRemote.SetVolume(20);
basicRemote.PowerOff();
Console.WriteLine();
advancedRemote.PowerOn();
advancedRemote.SetVolume(50);
((AdvancedRemoteControl)advancedRemote).Mute();
advancedRemote.PowerOff();
}
}
}
앞서 설명했듯이 기능을 추상화하고 구현체를 실게 구현하여 비슷한 구현체를 여러개 구현하여 독립적으로 확장할 수 있다.
예제의 경우 TV는 Samsung TV와 LG TV 같은 다양한 모델이 있을 수 있고, RemoteControl에는 일반 리모컨과 고급 리모컨이 있다고 가정해 보면 Bridge Pattern을 사용하여 RemoteControl의 인터페이스와 TV의 구현을 분리하면 TV나 리모컨이 독립적으로 확장할 수 있게 된다.
게임 개발에서는 몬스터나 캐릭터, 아이템 등 비슷한 구조를 가진 객체가 많이 있는데 이런 문제에 Bridge Pattern을 사용할 수 있는 패턴이다.