rainsister
  • 신비한 비 Blog
  • Design Pattern
    • Adapter Pattern
    • Proxy Pattern
    • Mediator Pattern
    • Visitor Pattern
    • State Pattern
    • Memento Pattern
    • Factory Pattern
    • Template Pattern
    • Strategy Pattern
    • Bridge Pattern
  • springboot 2.x
    • 메시징 - 큐
      • RabbitMQ 기본설정
      • RabbitMQ 지연 큐(delayed queue)
    • Log
      • 기본 Log 설정 및 Logback 설정
      • Log4j2 사용해보기
      • tinylog 모듈 사용해보기
    • 기타 Database 에 대한 기본가이드
      • PostgreSQL
      • InfluxDB
      • MongoDB
    • 수행속도 UP! 각종 cache 어노테이션 사용법
      • Redis를 사용하여 Cache 관리하기
      • EhCache 사용해보기
      • Thread내캐쉬사용 및 Cache 어노테이션 사용법
    • Database Connection
      • Springboot 2.5 이후 data init script 초기화에 대한 변경
      • JTA 로 JPA 다중 DataSource 트랜잭션 처리 하기
      • Flyway 로 DataBase 형상 관리해보자
      • 트랜잭션 기초읽기
      • MyBatis 의 다중 DataSource
      • Spring Data JPA 다중 DataSource
      • JdbcTemplate 다중 DataSource
      • XML 로 Mybatis 설정하기
      • Mybatis 로 Mysql 연결하기
      • ORM(Spring data jpa)
      • Druid datasource 연결
      • Hikari 설정
      • JdbcTemplate 로 db 접근
    • rest api
      • XML에 대한 요청 및 응답 처리
      • SpringFox 3 및 Swagger 설정
      • 프로젝트 구동 시 RequestMappingHandler 로그 설정
      • Swagger 의 api들을 분류하는 법
      • 간단한 Restful API 만들고 테스트 코드 작성
      • Swagger2 구성하여 API 문서 자동화하기
      • JSR-303 그리고 validation
    • 설정
      • 시작
      • 멀티환경구성에 대한 새로운 방법
      • 멀티환경구성에 대한 새로운 include
      • 프로젝트 설정파일
      • 민감한 정보에 대한 암호화
  • java버전별차이
    • JAVA18
    • JAVA9
    • JAVA10
    • JAVA11
    • JAVA14
    • JAVA15
    • JAVA17
    • JAVA16
  • spring노하우
    • BeanUtils 권장하지 않는이유
    • 개인정보 암호화
    • Springboot 3가지 CROS 설정
    • Springboot 내장된 유용한 Utils
    • Spring Security WebSecurityConfigurerAdapter 가 deprecated 된 이슈해결하기
    • 아직도 HttpUtil ? SpringBoot 3.0의 HTTP Client Util 을 사용해보라
    • JDBC 소스를 뽀개기
    • spring-boot-configuration-processor 는 뭐하는놈임?
    • Apache BeanUtils vs Spring BeanUtils 성능비교
  • Effetive Java 3th
    • Finalizer & Cleaner
Powered by GitBook
On this page
  • 정의
  • UML
  • 추상 클래스(Abstraction):
  • 구현 클래스 인터페이스(Implementor):
  • 확장 추상 클래스(Refined Abstraction):
  • 구현 클래스(Concrete Implementor):
  • 여담으로
  • 장단점
  • 어떤 경우 사용해야 할까?
  1. Design Pattern

Bridge Pattern

PreviousStrategy PatternNextspringboot 2.x

Last updated 8 months ago

정의

추상적인 부분과 그것의 실현된 부분을 분리하는 하고 모두 독립적으로 변화할 수 있도록 개발하는 패턴.

UML

각각의 역할

추상 클래스(Abstraction):

추상 인터페이스를 정의하면 집계 관계에서 추상 클래스에는 Implementor 유형의 객체가 포함되며, 이는 추상 비즈니스 방법과 특정 비즈니스 방법을 모두 포함할 수 있는 Implementor 유형 객체.

구현 클래스 인터페이스(Implementor):

구현 클래스의 인터페이스를 정의하며, 이 인터페이스는 Abstraction 클래스의 인터페이스와 다를 수 있습니다.일반적으로 구현 클래스 인터페이스는 기본 작업만 정의하는 반면 추상 클래스 인터페이스는 더 복잡한 작업을 수행할 수 있음.

확장 추상 클래스(Refined Abstraction):

추상 클래스에서 정의된 인터페이스를 구현하는 특정 클래스는 Implementor에서 정의된 방법으로 호출될 수 있음.

구현 클래스(Concrete Implementor):

구체적으로 Implementor 인터페이스를 구현하고 다른 특정 구현 클래스에서 다른 특정 작업을 구현합니다.실행 시 Concrete Implementor가 상위 클래스를 대체.

일반적인 사례를 예로들면, 우리 데스크탑에 여유저장 공간부족으로 하드를 새로 구입해서 메인보드에 장착한다고 생각해보자. 이 경우도 브릿지 패턴을 떠올릴수 있다. 데스크탑 전체를 교체하는게 아니라 필요한 용량의 하드디스크를 추가로 장착할수 있게 이미 소켓이 있기때문에 우리는 얼마든지 새로운 하드를 교체 및 추가 장착할수 있다. 뭐 요즘 나오는 IT 기계는 물론 자동차, 심시어 어린이 장난감도 기존 메인 바디에 비용을 추가하면 얼마든 새로운 아이템들을 추가하거나 확장할수 있다. 알고보면 프로그램의 디자인패턴도 결국은 일상생활에도 똑같이 적용되어 있을뿐 새로운 혁명같은 산물은 아니라는것이다.

그럼 코드로 한번 살펴보자.

아까 위에서 예를 들었던 데트크탑(PC)의 추상클래스를 만들어본다.

public abstract class Computer {
    protected HarddiskAPI harddiskAPI;

    public void setHarddiskAPI(HarddiskAPI harddiskAPI) {
        this.harddiskAPI = harddiskAPI;
    }

    public abstract void describe();
}

개인 데스크탑 이므로 기존 추상클래스를 상속받는다.

public class PCComputer extends Computer {
    @Override
    public void describe() {
        System.out.println("blake의 개인데스크탑!");
        harddiskAPI.add();
    }
}

뜬금없이 서버도 만들어보자

public class ServerComputer extends Computer {
    @Override
    public void describe() {
        System.out.println("blake server!");
        harddiskAPI.add();
    }
}

하드소켓을 추상화 해보자

public interface HarddiskAPI {
    void add();
}

필요한 사이즈가 512이므로 상속받아서 512사이즈 하드를 만들어보자

public class Harddisk512GAPI implements HarddiskAPI {
    @Override
    public void add() {
        System.out.println("512G 하드!");
    }
}

요즘 영화나 사진들이 모두 초고화질로 나오니 1TB 짜리 하드도 만들어보자

public class Harddisk1TAPI implements HarddiskAPI {
    @Override
    public void add() {
        System.out.println("1TB 하드!");
    }
}

테스트 코드 작성

public class BridgeTest {
    public static void main(String[] args) {
        Computer pc = new PCComputer();
        pc.setHarddiskAPI(new Harddisk512GAPI());
        pc.describe();

        Computer server = new ServerComputer();
        server.setHarddiskAPI(new Harddisk1TAPI());
        server.describe();
    }
}

여담으로

장단점

장점: 브리지 모드는 추상 부분과 구현 부분을 분리하여 인터페이스를 별도로 정의하므로, 추상 부분과 구현 부분이 서로 영향을 주지 않고 각각 독립적으로 확장될 수 있다.

단점: 브리지 모드는 시스템에서 두 개의 독립적인 차원을 정확하게 식별해야 하므로 사용 범위에 특정 제한이 있다.

어떤 경우 사용해야 할까?

시스템이 두 계층 간의 정적 상속 연결을 피하기 위해 구성 요소의 추상화된 역할과 구체화된 역할 사이에 더 많은 유연성을 추가해야 하는 경우 브리지 모드를 통해 추상 계층에서 관계를 설정할 수 있다.클래스에는 두 개의 독립적으로 변화하는 차원이 있으며 이 두 차원은 모두 확장되어야 하며 브리지 모드에도 적용할 수 있다.

우리는 좀 더 나아가서 spring에서 사용하는

JDBC 의 소스를 깊게 파보자.