[디자인 패턴] Bridge 패턴

한낱·2023년 8월 13일

디자인 패턴

목록 보기
2/6

서론

일반적으로 다리는 서로 다른 두 장소를 연결할 때 사용된다. 마찬가지로 Bridge 패턴에서는 기능을 추가할 때 사용하는 클래스 계층과 구현을 하려할 때 사용하는 클래스 계층이 등장하고 이 두 클래스 계층을 연결한다는 의미로 Bridge라는 이름이 붙었다.
패턴 클래스 다이어그램

상속과 위임

Bridge 패턴의 클래스 다이어그램을 살펴보면 RefinedAbstraction에서 Abstraction으로 뻗어간 화살표는 상속을 나타낸다. Abstraction에서 Implementor로 뻗어간 화살표는 위임을 나타낸다.

  • 상속은 클래스의 확장을 편리하게 할 수 있지만, 소스코드를 다시 쓰지 않는 한 관계를 바꿀 수 없어 클래스 간의 연결이 강하게 고정된다.
  • 반면 위임은 클래스 간의 관계를 전환하기 적합하다. 따라서, 상속은 '강한 결합'이고, 위임은 '약한 결합'이라고 표현한다.

여러 클래스를 이용하여 설계를 진행할 때에는 클래스 간의 결합 관계를 잘 이해하고 사용하는 것이 중요하다.

본론

구현의 클래스 계층

public abstract class DisplayImpl {
  public abstract void rawOpen();
  public abstract void rawPrint();
  public abstract void rawClose();
}

이 DisplayImpl 클래스는 구현의 클래스 계층에서 최상위에 위치하는 클래스로 추상클래스로 만들어져 있다. 해당 클래스의 하위 클래스인 StringDisplayImpl 클래스는 이를 구현하여 문자열을 표시하는 클래스를 만든다.

public class StringDisplayImpl extends DisplayImpl {
  private String string;
  private int width;

  public StringDisplayImpl(Stirng string) {
    this.string = string;
    this.width = string.length();
  }

  @Override
  public void rawOpen() {
      printLine();
  }

  @Override
  public void rawPrint() {
      System.out.println("|" + string + "|");
  }

  @Override
  public void rawClose() {
    printLine();
  }

  private void printLine() {
    System.out.print("+");
    for (int i = 0; i < width; i++) {
    System.out.print("-");
    }
    System.out.println("+");
  }
}

기능의 클래스 계층

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();
   	}
}
  

Display 클래스는 기능의 클래스 계층 최상위에 있는 클래스이다. Display 클래스의 impl 필드가 기능의 클래스 계층과 구현의 클래스 계층을 연결하는 다리 역할을 한다.
Display 클래스에서 제공하는 인터페이스를 실현하기 위해 impl 필드의 구현 메서드를 사용하면서 Display의 인터페이스가 DisplayImpl의 인터페이스로 변환된다.

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();
  }
}

CountDisplay 클래스는 표시하는 기능밖에 존재하지 않던 Display 클래스에 '지정 횟수만큼 표시한다'는 기능을 추가하기 위해 만들어진 클래스이다.

Bridge 패턴 사용

public class Main {
  public static void main(String[] args) {
    Display d1 = new Display(new StringDisplayImpl("Hello, Korea."));
    Display d2 = new CountDisplay(new StringDisplayImpl("Hello, Worlds."));
    CountDisplay d3 = new CountDisplay(new StringDisplayImpl("Hello, Universe."));
    d1.display();
    d2.display();
    d3.display();
    d3.multiDisplay(5);
  }
}

display 결과

Bridge 패턴의 장점

Bridge 패턴은 기능과 구현의 클래스 계층을 분리함으로써 각각의 클래스 계층을 독립적으로 확장할 수 있도록 한다. 덕분에 기능의 추가가 구현 클래스 계층에는 영향을 미치지 않는다. 또한, 기능 클래스 계층에서 추가된 기능은 모든 구현 클래스 계층에서 동일하게 이용할 수 있다.

예시

어떤 프로그램이 컴퓨터나 운영체제같은 실행 환경에 의존하는 부분이 있다면 각 실행 환경에 의존하는 부분을 구현의 클래스 계층에 분리해 구현해두면, 새로운 기능이 추가되어도 모든 실행환경에서 동시에 대응할 수 있다.

profile
제일 재밌는 개발 블로그(희망 사항)

0개의 댓글