Updated:

1. 개요

구현부에서 추상층을 분리하여 독립적으로 다양성을 가질 수 있도록 하는 패턴

가교 패턴(Bridge Pattern)은 구조 패턴(Structural Pattern)의 한 종류로, 구현과 추상을 분리하여 재사용성을 높이고, 컴파일 시점이 아닌 런타임 시점에 구현체를 선택하도록 하여 유연한 설계가 가능하도록 하는 패턴이다.

2. 구조 패턴(Structural Pattern)

2-1. 구조 패턴이란?

구조 패턴이란 작은 클래스들의 상속과 합성을 통해 더 큰 클래스를 생성하는 방법을 제공하는 패턴으로, 독립적으로 개발한 클래스들을 마치 하나인 것 처럼 사용할 수 있다.

2-2. 구조 패턴 종류

3. 구성

[출처 : GoF의 디자인 패턴]

  • Abstraction : 기능 계층의 최상위 클래스로, 기능을 정의한 인터페이스

  • RefinedAbstraction : Abstraction 인터페이스를 확장한 클래스

  • Implementor : Abstraction의 기능을 구현하기 위한 인터페이스

  • ConcreteImplementor : Implementor 인터페이스를 구현한 클래스

4. 예제 코드

삼성 선풍기와 LG 선풍기를 리모컨으로 동작 가능하도록 기능을 확장한다고 가정해보자. 추상 클래스를 확장하여 리모컨 동작 기능을 추가하고, 기존에 구현한 선풍기 클래스와 연결해주어야 한다.

4-1. Implementor

[Fan.java]

1
2
3
4
5
public interface Fan {

    void turnOn();
    void turnOff();
}

4-2. ConcreteImplementor

[SamsungFan.java]

1
2
3
4
5
6
7
8
9
10
11
12
public class SamsungFan implements Fan {

    @Override
    public void turnOn() {
        System.out.println("Turn on samsung fan");
    }

    @Override
    public void turnOff() {
        System.out.println("Turn off samsung fan");
    }
}

[LgFan.java]

1
2
3
4
5
6
7
8
9
10
11
12
public class LgFan implements Fan {
    
    @Override
    public void turnOn() {
        System.out.println("Turn on lg fan");
    }

    @Override
    public void turnOff() {
        System.out.println("Turn off lg fan");
    }
}

4-3. Abstraction

[Device.java]

1
2
3
4
5
public interface Device {

    void turnOn();
    void turnOff();
}

4-4. RefinedAbstraction

[RemoteDevice.java]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class RemoteDevice implements Device {

    private Fan fan;

    public RemoteDevice(Fan fan) {
        this.fan = fan;
    }

    @Override
    public void turnOn() {
        System.out.println("Use remote control");
        fan.turnOn();
    }

    @Override
    public void turnOff() {
        System.out.println("Use remote control");
        fan.turnOff();
    }
}

5. 테스트

[Clinet.java]

1
2
3
4
5
6
7
8
9
10
11
12
public class Client {

    public static void main(String[] args) {
        Device device1 = new RemoteDevice(new SamsungFan());
        device1.turnOn();
        device1.turnOff();

        Device device2 = new RemoteDevice(new LgFan());
        device2.turnOn();
        device2.turnOff();
    }
}

[실행 결과]

6. 특징

  • 인터페이스와 구현체 분리 : 인터페이스와 구현체가 분리되어 런타임 시점에 구현 클래스를 자유롭게 변경 가능

  • 낮은 결합도 : 인터페이스와 구현체를 각각 독립적으로 확장 가능하므로 낮은 결합도 유지 가능

  • 상세 구현 은닉 : 클라이언트가 인터페이스에만 의존하므로 상세 구현 은닉 가능

7. Adapter vs Bridge

  • Adapter Pattern

    • 이미 존재하는 두 인터페이스 간의 불일치 해결

    • 인터페이스의 구현 방법 등은 고려하지 않음

    • 설계가 완료된 후 호환되지 않은 부분에 적용

  • Bridge Pattern

    • 정의와 구현을 따로 만들어서 연결

    • 새로운 구현의 추가 가능

    • 설계가 완료되기 전 추상과 개념을 각각 독립적으로 확장 가능

Updated:

Leave a comment