Design Pattern | Bridge Pattern (브릿지 패턴)
Bridge 패턴이란?
- Bridge라는 영어 단어는 다리라는 의미이다.
- 현실 세계의 다리가 강가를 양쪽으로 연결시키는 것처럼, Bridge 패턴도 2개의 장소를 연결하는 방식이다.
- 구현과 추상을 분리. ‘기능 클래스 계층’과 ‘구현 클래스 계층’간에 다리(Bridge)를 놓는 역할을 하는 패턴이다.
- Bridge 패턴이 교차하는 두 위치는 기능 클래스 계층과 구현 클래스 계층이 된다.
- 기능 클래스의 계층 : 슈퍼 클래스로 기본적인 기능을 가지고 있어, 서브 클래스로 새로운 기능을 추가하는 경우의 계층이다.
- 구현 클래스의 계층 : 슈퍼 클래스로 추상 메소드에 의해 인터페이스를 규정하고 있어, 서브 클래스에서 구상 메소드에 의해 그 인터페이스를 구현하는 경우의 계층이다.
- GoF의 디자인 패턴에서는 구조와 관련된 디자인 패턴으로 분류된다.
Bridge 패턴 예제 프로그램
입력한 문자열을 지정 횟수 및 랜덤 횟수 표시하는 예제 프로그램이다.
Class Diagram
1. Display 클래스
기능 클래스 계층이 되는 “표시"를 실시하는 클래스이다.
이 클래스가 가지는 impl
필드가 2개의 클래스 계층의 “다리"가 된다.
Display.java
package com.devkuma.designpattern.structural.bridge;
public class Display {
private DisplayImpl impl;
public Display(DisplayImpl impl) {
this.impl = impl;
}
public void open() {
impl.rawOpen();
}
public void print() {
impl.rawPrint();
}
public void close() {
impl.rawClose();
}
public final void display() {
open();
print();
close();
}
}
2. CountDisplay 클래스
기능 클래스 계층이 되는 “지정 횟수 표시"라고 하는 기능을 추가한 클래스이다.
CountDisplay.java
package com.devkuma.designpattern.structural.bridge;
public class CountDisplay extends Display {
public CountDisplay(DisplayImpl impl) {
super(impl);
}
public void multiDisplay(int times) {
open();
for (int i = 0; i < times; i++) {
print();
}
close();
}
}
3. RandomCountDisplay 클래스
기능 클래스 계층이 되는 “랜덤 횟수 표시"라는 기능을 추가한 클래스이다.
RandomCountDisplay.java
package com.devkuma.designpattern.structural.bridge;
import java.util.Random;
public class RandomCountDisplay extends CountDisplay {
private Random random = new Random();
public RandomCountDisplay(DisplayImpl impl) {
super(impl);
}
public void randomDisplay(int times) {
multiDisplay(random.nextInt(times));
}
}
4. DisplayImpl 클래스
구현 클래스 계층이 되는 “표시"용의 메소드를 정의한 클래스이다.
DisplayImpl.java
public abstract class DisplayImpl {
public abstract void rawOpen();
public abstract void rawPrint();
public abstract void rawClose();
}
5. StringDisplayImpl 클래스
구현 클래스 계층이 되는 “문자열을 사용해 표시"하는 클래스이다.
StringDisplayImpl.java
package com.devkuma.designpattern.structural.bridge;
public class StringDisplayImpl extends DisplayImpl {
private String string;
private int width;
public StringDisplayImpl(String string) {
this.string = string;
this.width = string.getBytes().length;
}
public void rawOpen() {
printLine();
}
public void rawPrint() {
System.out.println("|" + string + "|");
}
public void rawClose() {
printLine();
}
private void printLine() {
System.out.print("+");
for (int i = 0; i < width; i++) {
System.out.print("-");
}
System.out.println("+");
}
}
6. Main 클래스
메인 처리를 실행하는 클래스이다.
Main.java
package com.devkuma.designpattern.structural.bridge;
public class Main {
public static void main(String[] args) {
Display display = new Display(new StringDisplayImpl("Display Test"));
CountDisplay countDisplay = new CountDisplay(new StringDisplayImpl("CountDisplay Test"));
RandomCountDisplay randomCountDisplay = new RandomCountDisplay(new StringDisplayImpl("RandomCountDisplay Test"));
display.display();
countDisplay.multiDisplay(5);
randomCountDisplay.randomDisplay(10);
}
}
7. 실행 결과
+------------+
|Display Test|
+------------+
+-----------------+
|CountDisplay Test|
|CountDisplay Test|
|CountDisplay Test|
|CountDisplay Test|
|CountDisplay Test|
+-----------------+
+-----------------------+
|RandomCountDisplay Test|
|RandomCountDisplay Test|
|RandomCountDisplay Test|
|RandomCountDisplay Test|
|RandomCountDisplay Test|
|RandomCountDisplay Test|
+-----------------------+
장점
앞서 언급했듯이 브릿지 패턴의 특징은 기능 클래스의 계층과 구현 클래스의 계층을 구분한다는 것이다. 이 2개의 클래스 계층을 나누어 두면, 각각의 클래스 계층을 독립적으로 확장할 수 있다.
기능을 추가하려면 함수의 클래스 계층에 클래스를 추가한다. 이 때, 구현 클래스 계층은 전혀 수정할 필요는 없다. 게다가, 추가한 기능은 모든 구현으로 이용할 수 있게 된다.
예제 프로그램에서는, CountDisplay 클래스나 RandomCountDisplay 클래스를 추가하는 것이 기능 추가에 해당한다.
이와 같이 Bridge 패턴에서는 클래스의 확장을 전망하고 잘 할 수 있다.
최종 수정 : 2022-03-17