Bridge Pattern
View all Design Patterns
모놀리식(monolithic) 클래스를 구현 부분과 추상 부분으로 나누어, 여러 개의 클래스 각각의 계층 구조로 분할하는 방법이다. 이로써 구현 부분을 숨길 수 있게 된다. 또한 클래스를 변경할 때, 다른 클래스와 독립적으로 변경할 수 있게 된다. (Bridge라는 이름은 구현 부분과 추상 부분 간의 연결을 의미한다.)
Bridge Pattern과 Adapter Pattern의 차이점은 다음과 같다.
- Adapter Pattern은 기존의 코드 베이스가 이미 존재할 경우, 호환이 가능하게 하기 위함이다.
- 반면에, Bridge Pattern은 최초 설계 시, 각 클래스로 분할해 독립적으로 개발하기 위함이다.
Class Diagram
Abstract overview
여기에서 클라이언트는 Abstraction
에 의존하게 되어, 구체적인 구현부를 숨길 수 있다.
Concrete example
Code
interface MessageSender {
send(message: string): void;
}
class EmailSender implements MessageSender {
send(message: string): void {
console.log(`Email message: ${message}`);
}
}
class SMSSender implements MessageSender {
send(message: string): void {
console.log(`SMS message: ${message}`);
}
}
abstract class AbstractMessage {
protected messageSender: MessageSender;
constructor(messageSender: MessageSender) {
this.messageSender = messageSender;
}
abstract sendMessage(message: string): void;
}
class NoticeMessage extends AbstractMessage {
sendMessage(message: string): void {
console.log("Sending notice message...");
this.messageSender.send(message);
}
}
class GeneralMessage extends AbstractMessage {
sendMessage(message: string): void {
console.log("Sending general message...");
this.messageSender.send(message);
}
}
const emailSender = new EmailSender();
const smsSender = new SMSSender();
const noticeMessageByEmail = new NoticeMessage(emailSender);
const generalMessageBySMS = new GeneralMessage(smsSender);
noticeMessageByEmail.sendMessage("This is a notice message");
// Sending notice message...
// Email message: This is a notice message
generalMessageBySMS.sendMessage("This is a general message");
// Sending general message...
// SMS message: This is a general message
위 코드에서 AbstractMessage
와 MessageSender
가 서로 분리 돼 있기 때문에, 하나가 변경 돼도 다른 코드에 영향을 주지 않는다. 또한, 각 상속받은 메시지 클래스(NoticeMessage
, GeneralMessage
)에 전달할 객체만 바꿔서 메시지 전송 방식을 쉽게 변경할 수 있다.
Pros and Cons
Pros
- 추상 클래스(
Abstraction
또는AbstractMessage
)에만 의존하기 때문에 세부 사항에 의존하지 않을 수 있으며, 따라서 SRP(Single Responsibility Principle, 단일책임원칙)를 준수할 수 있다.
Cons
- 추가적인 추상 클래스와 인터페이스를 필요로 하기 때문에, 코드의 복잡성이 증가할 수 있다.