개발/디자인패턴

[Java][디자인 패턴] 8. 브리지 패턴 (Bridge Pattern)

nova_dev 2022. 3. 7. 23:59
반응형

디자인패턴
[Java][디자인 패턴] 8. 브리지 패턴

브리지 패턴은 객체의 확장성을 향상하기 위한 패턴으로, 객체에서 동작을 처리하는 구현부와 확장을 위한 추상부를 분리한다.

 

 브리지 패턴이란?

  • 브리지 패턴은 기능을 처리하는 클래스와 구현을 담당하는 추상 클래스로 구별한다. 구현뿐 아니라 추상화도 독립적 변경이 필요할 때 브리지 패턴을 사용한다.
  • 2개의 객체는 추상화를 구현에서 분리하여 매우 독립적으로 사용할 수 있어야 한다.
  • 브리지 패턴은 기존 시스템에 부수적인 새로운 기능들을 지속적으로 추가할 때 사용하면 유용하다.
  • 브리지 패턴은 새로운 인터페이스를 정의하여 기존 프로그램의 변경 없이 기능을 확장할 수 있다.

 브리지 패턴은 언제 사용하면 좋을까?

  • 부모 추상 클래스가 기본 규칙 세트를 정의하고 구체적인 클래스가 추가 규칙을 추가하고 싶은 경우
  • 객체에 대한 참조가 있는 추상 클래스가 있고 각 구체적인 클래스에서 정의될 추상 메서드가 있는 경우

 

 

 브리지 패턴의 구성 요소

브리지 패턴 구성요소

  • Implementor
    - abstract 기능을 구현하기 위한 인터페이스 정의
  • ConcreateImplementor
    - 실제 기능 구현
  • Abstract
    - 기능 계층의 최상위 클래스
    - 구현 부분에 해당하는 클래스를 인스턴스를 가지고 구현부 메서드를 호출한다
  • RefinedAbstract
    - 기능 계층에서 새로운 부분을 확장한 클래스

 브리지 패턴의 예제 코드 구조

브리지 패턴 예제 코드 (Brush)

  • Color (Implementor)
  • Blue, Red (ConcreateImplementor)
  • Brush (Abstract)
  • MonoLine, HBPencil (RefinedAbstract)

위에서 설명한 브리지 패턴 구조와 위 예조 코드를 대입해서 이해하면 쉬울 것 같다.
Color라는 기능을 구현하고 있는 Blue, Red 클래스가 있고, 해당 기능을 사용하여 실제 구현을 담당하는 Brush 추상 클래스와 해당 추상 클래스의 draw 메서드의 구현을 담당하고 있는 Monoline, HBPencil 클래스가 있다.

위 예제 코드는 Baeldung의 예제 코드를 참고해서 나름대로 수정해서 만들었다. 아래 원본 코드는 아래를 참고!
참고 링크: https://www.baeldung.com/java-bridge-pattern

 브리지 패턴 코드

1. Color 인터페이스와 Red, Blue 구체 클래스

public interface Color {
    String fill();
}
public class Red implements Color {
    @Override
    public String fill() {
        return "발간색";
    }
}
public class Blue implements Color {
    @Override
    public String fill() {
        return "파란색";
    }
}

2. Brush 추상 클래스

public abstract class Brush {
    protected Color color;

    protected Brush(Color color) {
        this.color = color;
    }

    public abstract String draw();

}

3. Brush 추상 클래스를 상속받아 draw 메서드를 구현하고 있는 HBPencil 클래스와 MonoLine 클래스

public class HBPencil extends Brush {
    public static final String type = "[HB 연필]";

    public HBPencil(Color color) {
        super(color);
    }

    @Override
    public String draw() {
        return type + " " + color.fill();
    }
}
public class MonoLine extends Brush {
    public static final String type = "[모노라인]";

    public MonoLine(Color color) {
        super(color);
    }

    @Override
    public String draw() {
        return type + " " + color.fill();
    }
}

3. 브리지 패턴 테스트 코드 (Brush 테스트 코드)

import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

class BrushTest {

    @Test
    @DisplayName("브리지 패턴 테스트")
    void brushColorTest() {
        Brush redBrush = new HBPencil(new Red());
        Assertions.assertThat("[HB 연필] 빨간색".equals(redBrush.draw()));

        Brush blueBrush = new MonoLine(new Blue());
        Assertions.assertThat("[모노라인] 파란색".equals(blueBrush.draw()));
    }
}

 브리지 패턴의 특징

  • 브리지 패턴은 복합 객체를 다시 재정의하여 추상 계층화된 구조이다. 구성 클래스의 연결 부분을 추상 클래스로 변경한다. 이를 통해 각각의 계층이 독립적으로 확장 및 변경 가능해진다.
  • 브리지 패턴은 기능을 처리하는 클래스와 구현을 담당하는 추상 클래스로 구별한다. 구현 뿐 아니라 추상화도 독립적 변경이 필요할 때 브리지 패턴을 사용한다.
  • 브리지는 상속 대신 구현을 통해 분리된 객체를 연결한다. 구현을 통해 객체를 연결하면 객체 간 종속 관계를 제거할 수 있다.
  • 브리지 패턴에서 기능과 구현을 분리하여 확장을 보다 쉽게 할 수 있다. 분리된 계층은 독립적으로 확장 가능하다.

 브리지 패턴의 장점과 단점

장점

  • 클래스 계청을 분리할 때 완전한 인터페이스를 결합하지 않는다. 이를 통해 클래스에서 구현과 추상 부분 2개의 계층으로 분리할 수 있고, 분리된 2개의 추상 계층과 구현 계층은 독립적인 확장이 가능하다.
  • 브리지 패턴을 사용하면 런타임 시점에 어떤 방식으로 기능을 구현할지 선택할 수 있다.
  • 기능을 독립적으로 확장할 수 있다면 상세한 기능을 외부로부터 숨길 수 있는 은닉 효과도 얻을 수 있다.

단점

  • 추상화를 통해 코드를 분리할 경우 코드 디자인 설계가 복잡해진다는 단점이 있다.

 Github 코드

Github 예제 코드 링크

Github 예제 테스트 코드 링크

참고 자료

 

 

 

 

 

반응형