Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- AES256
- 디버깅
- scrapy
- Ai
- Vue 강의
- IntelliJ
- intellij완전정복
- 민생회복지원금
- 개발툴팁
- 개발생산성
- 주식용어
- GPT
- Spring
- python
- docker
- Vue 알아보기
- spring boot 시작
- JetBrains
- Vue 배우기
- docker mysql
- python 기초
- 지원금신청방법
- Spring Batch 강의
- Python 기본편
- 자바패턴
- gradle
- intelliJ plugin
- 미국 배당주
- java
- MYSQL
Archives
나만의공간
🧱 1. 브리지 패턴이란? 본문
브리지 패턴(Bridge Pattern) 완전 정복 - 자바 실무 예제로 이해하기
디자인 패턴 중에서 기능 계층과 구현 계층을 분리하여 구조를 유연하게 만들어주는 브리지 패턴(Bridge Pattern)에 대해 들어보셨나요?
이 글에서는 어댑터 패턴(Adapter Pattern)과 비교되는 브리지 패턴의 개념부터 자바 실무 예제까지 쉽게 정리해드립니다.
✅ 브리지 패턴이란?
브리지 패턴(Bridge Pattern)은 기능(추상)과 구현(구체)을 독립적으로 분리하여 확장이 용이하도록 돕는 구조 디자인 패턴입니다.
- 클래스 간 결합도를 낮추기 위해 상속 대신 위임을 활용
- 새로운 기능이나 구현이 추가될 때 기존 클래스에 영향 없이 확장 가능
📌 Adapter Pattern과의 차이점
어댑터 패턴(Adapter Pattern)은 기존 클래스를 다른 인터페이스에 맞게 변환할 때 사용되고, 브리지 패턴은 처음부터 구조적으로 기능과 구현을 나누어 설계할 때 사용됩니다.
🎨 브리지 패턴을 리모컨과 TV로 쉽게 이해하기
리모컨 (기능) | TV (구현) |
---|---|
켜기 / 끄기 | LG, 삼성, 소니 등 |
- 리모컨은 동작만 정의하고, 어떤 TV를 켤지는 리모컨이 내부적으로 알고 있음
- 새로운 리모컨 or TV 추가 시 기존 코드 수정 없이도 확장 가능
📌 브리지 패턴이 필요한 시점
- 구현 클래스가 다양하고, 기능과 구현을 각각 독립적으로 확장해야 할 때
- UI 테마, OS별 처리, 디바이스 종류 등 조합이 많을 때
- 클래스 수가 폭발하는 상황을 방지하고 싶을 때
🎯 예제 시나리오: 메시지 전송 시스템
전송 수단은 Email
, Slack
, 메시지 유형은 긴급
, 일반
으로 구성된 시스템이 있다고 가정해봅시다.
기존 방식대로라면 각 조합마다 클래스를 만들거나 if-else
조건문이 난무할 수 있죠. 이럴 때 브리지 패턴을 적용하면, 각 계층을 독립적으로 구현하고 조합할 수 있어 훨씬 깔끔한 구조가 됩니다.
🔧 실무 자바 예제로 보는 브리지 패턴
1️⃣ 구현체 인터페이스
public interface MessageSender {
void send(String message);
}
2️⃣ 구현체 클래스: Email / Slack
public class EmailSender implements MessageSender {
@Override
public void send(String message) {
System.out.println("[EMAIL] " + message);
}
}
public class SlackSender implements MessageSender {
@Override
public void send(String message) {
System.out.println("[SLACK] " + message);
}
}
3️⃣ 추상 클래스: 메시지
public abstract class Message {
protected MessageSender sender;
public Message(MessageSender sender) {
this.sender = sender;
}
public abstract void sendMessage(String content);
}
4️⃣ 구체 메시지 클래스
public class UrgentMessage extends Message {
public UrgentMessage(MessageSender sender) {
super(sender);
}
@Override
public void sendMessage(String content) {
sender.send("[긴급] 🚨 " + content);
}
}
public class NormalMessage extends Message {
public NormalMessage(MessageSender sender) {
super(sender);
}
@Override
public void sendMessage(String content) {
sender.send("[일반] 📩 " + content);
}
}
5️⃣ 클라이언트 코드
public class Main {
public static void main(String[] args) {
MessageSender email = new EmailSender();
MessageSender slack = new SlackSender();
Message urgentViaEmail = new UrgentMessage(email);
Message normalViaSlack = new NormalMessage(slack);
urgentViaEmail.sendMessage("결제 오류 발생!");
normalViaSlack.sendMessage("정기 리포트 발송");
}
}
✅ 실행 결과
[EMAIL] [긴급] 🚨 결제 오류 발생!
[SLACK] [일반] 📩 정기 리포트 발송
📦 UML 구조 요약
[MessageSender] ◄────────────┐
▲ │
[EmailSender], [SlackSender] │
│
[Message] ◄─────────────────┘
▲
[UrgentMessage], [NormalMessage]
💡 장점과 단점 비교
항목 | 설명 |
---|---|
✅ 장점 | 기능과 구현을 독립적으로 확장 가능 조합 수가 많아도 클래스 수 최소화 SRP, OCP 등 SOLID 원칙 준수 |
❌ 단점 | 구조가 익숙하지 않으면 복잡하게 느껴질 수 있음 간단한 기능엔 과한 설계가 될 수 있음 |
🛠 실무에서의 사용 예
- Spring Framework에서 전략 객체 분리
- 다양한 OS 환경에서 UI 컴포넌트 분리
- PDF/HTML/Excel 등 다양한 형식의 보고서 출력기
📝 마무리 정리
항목 | 내용 |
---|---|
패턴 이름 | 브리지 패턴 (Bridge Pattern) |
주요 목적 | 기능 계층과 구현 계층을 분리하여 독립적 확장 |
주요 구성 요소 | Abstraction, Implementor, RefinedAbstraction, ConcreteImplementor |
적용 시점 | 조합 수가 많고, 클래스 수가 늘어날 때 |
📌 관련 디자인 패턴도 함께 알아두세요
- 어댑터 패턴(Adapter Pattern): 기존 코드를 다른 인터페이스에 맞게 변환할 때 사용
- 데코레이터 패턴: 기능을 런타임에 동적으로 확장할 때 유용
- 전략 패턴: 알고리즘을 캡슐화하고 동적으로 교체 가능
'IT > JAVA' 카테고리의 다른 글
🧱 데코레이터 패턴 완전 정복 - 커피 주문 예제로 배우는 디자인 패턴 (0) | 2025.06.01 |
---|---|
🧱 1. 복합체 패턴이란? (0) | 2025.05.31 |
🧱 1. 어댑터 패턴이란? (0) | 2025.05.31 |
🧱 1. 싱글턴 패턴이란? (2) | 2025.05.30 |
🧱 1. 프로토타입 패턴이란? (0) | 2025.05.30 |
Comments