Ian's Archive 🏃🏻

Profile

Ian

Ian's Archive

Developer / React, SpringBoot ...

📍 Korea
Github Profile →
Categories
All PostsAlgorithm19Book1C1CI/CD2Cloud3DB1DesignPattern9ELK4Engineering1Front3Gatsby2Git2IDE1JAVA7JPA5Java1Linux8Nginx1PHP2Python1React9Security4SpatialData1Spring26
thumbnail

브릿지 패턴 정리

DesignPattern
2025.11.04.

1. 브릿지 패턴

  • 추상적인 것과 구체적인 것을 분리하여 연결하는 패턴
  • 브릿지 패턴의 핵심은 “기능 클래스 계층” 과 “구현 클래스 계층” 의 분리
    • 기능 클래스 : 기본 기능을 가지고 있는 부모 클래스를 상속 받아 새로운 기능이 추가된 하위 클래스
    • 구현 클래스 : 기능을 정의한 추상 클래스(or 인터페이스)의 기능을 구현한 하위 클래스
  • 클래스 계층이 하나여서 기능과 구현이 함께 있으면, 새로운 기능이 추가될 수록 무거워짐
    • 이로 인해 한개의 클래스 권한이 너무 커지고 의존하는 형태
    • 2가지 계층을 분리해서 관리하고 2계층을 연결하기 위한 패턴이 브릿지 패턴

2. 브릿지 패턴 구조 및 특징

  • 클라이언트는 구현체를 직접 사용하지 않고 추상적인 인터페이스를 사용
  • 하나의 계층 구조일 때 보다 2개의 계층구조(기능, 구현)로 나누었을 때 독립적인 계층 구조로 발전 가능

2

상속

  • 상속은 상위 클래스에 공통 로직을 구현해두고, 자식 클래스에서 이를 재사용하는 방법
  • 흔히 Is-a 관계라고 불림
복사
public class Person {

    public void walk() {
        System.out.println("걷다");
    }

    public void talk() {
        System.out.println("말한다.");
    }
}

public class Chef extends Person {
    
}

합성

  • 합성은 중복되는 로직들을 가지는 객체를 구현하고, 이를 주입받아 호출해서 재사용하는 방법
  • 상속과 유사하지만, 한 클래스가 다른 클래스의 객체를 포함하는 관계이기 때문에 Has-a 관계라고 불림
복사
public class Chef {

    private Person person;
    private List<Food> foodList;
    
    public Chef(Person person, List<Food> foodList) {
    	this.person = person;
      this.foodList = foodList;
    }

    public int calculatePrice() {
        return foodList.stream()
            .mapToInt(v -> v.getPrice())
            .sum();
	}
}

public class Person {

    public void walk() {
        System.out.println("걷는다");
    }

    public void talk() {
        System.out.println("말한다");
    }
}

3. 브릿지 패턴 구현

  1. 공통 기능(행동)을 정의해둔 인터페이스 정의
복사
public interface Champion {

    void move();
    void skillQ();
    void skillW();
    void skillE();
    void skillR();
}

public interface Skin {

    String getName();
}


//Skin 구현체들
public class PoolParty_skin implements Skin{

    @Override
    public String getName() {
        return "PoolParty Skin";
    }
}

public class KDA_skin implements Skin{

    @Override
    public String getName() {
        return "KDA Skin";
    }
}
  1. 구현 클래스 구현
  • DefaultChampion은 Champion의 기능을 구현한 1개의 구현 클래스 계층
  • DefaultChampion은 Skin을 외부에서 주입받아 멤버 변수로 가지고 있다.
  • Skin은 기능을 정의만 한 인터페이스 이므로, 외부에서 Skin을 구현한 또 다른 구현 계층 클래스를 주입받아야 한다.
  • 외부에서 주입받는 Skin필드가 두 클래스 계층을 연결하는 **다리(Bridge)**가 된다.
복사
public class DefaultChampion implements Champion {

    private Skin skin;
    private String name;

    public DefaultChampion(Skin skin, String name) {
        this.skin = skin;
        this.name = name;
    }

    @Override
    public void move() {
        System.out.printf("%s %s move\n", skin.getName(), this.name);
    }

    @Override
    public void skillQ() {
        System.out.printf("%s %s Q skill \n", skin.getName(), this.name);
    }

    @Override
    public void skillW() {
        System.out.printf("%s %s W skill \n", skin.getName(), this.name);
    }

    @Override
    public void skillE() {
        System.out.printf("%s %s E skill \n", skin.getName(), this.name);
    }

    @Override
    public void skillR() {
        System.out.printf("%s %s R skill \n", skin.getName(), this.name);
    }
}
  1. 클라이언트 코드
  • 브릿지 패턴으로 계층구조를 분리한 후 연결하니, 서로 다른 계층 구조에서 추가적인 요구사항에 따라 확장이 가능해짐
  • 클라이언트에서 사용할 계층 구조를 주입하여 2계층 구조를 연결해주는 구조가 완성
복사
public class App {

    public static void main(String[] args) {

        Champion kda아리 = new 아리(new KDA_skin());
        kda아리.move();
        kda아리.skillQ();

        Champion poolParty아리 = new 아리(new PoolParty_skin());
        poolParty아리.move();
        poolParty아리.skillR();

    }
}


public class 아리 extends DefaultChampion {

    public 아리(Skin skin) {
        super(skin, "아리");
    }
}

public class 아칼리 extends DefaultChampion {

    public 아칼리(Skin skin) {
        super(skin, "아칼리");
    }
}

4. 브릿지 패턴을 적용하지 않으면

  • 계층 구조가 무거워짐에 따라 중복 코드가 늘고, 모든 기능을 한 객체에서 관리하기에 의존도도 높아진다.
  • 각기 다른 세부적인 특징들이 달라질수록 그에 따른 구현체들도 기하 급수적으로 늘어나게 된다.

5. 브릿지 패턴 장점 및 단점

장점

  • 추상적인 코드를 구체적인 코드 변경 없이도 독립적으로 확장 가능
  • 추상적인 코드와 구체적인 코드를 분리할 수 있다.

단점

  • 계층 구조가 늘어나 복잡도가 증가할 수 있다.

Reference

코딩으로 학습하는 GoF의 디자인 패턴 - 백기선

Previous Post
복합체(Composite) 패턴 정리
Next Post
데코레이터(Decorator) 패턴 정리
Thank You for Visiting My Blog, I hope you have an amazing day 😆
© 2023 Ian, Powered By Gatsby.