브릿지(Bridge) 패턴
브리지 패턴은 구현부와 추상부를 분리하여 독립적으로 확장할 수 있도록 설계하는 구조적 디자인 패턴입니다. 이 패턴은 기능 계층과 구현 계층을 분리해 결합도를 낮추고 확장성을 높여줍니다.
문제점: 기능과 구현의 결합
애플리케이션에서 다양한 기능과 구현 방법을 동시에 처리해야 할 때, 클래스가 기하급수적으로 증가하는 문제가 발생합니다. 예를 들어, 다양한 색상의 모양(원, 사각형 등)을 구현한다고 할 때, 색상과 모양의 조합만큼 클래스를 생성해야 합니다.
// 다양한 색상과 모양을 구현해야 할 경우
class RedCircle {
public void draw() {
System.out.println("Drawing Red Circle");
}
}
class BlueCircle {
public void draw() {
System.out.println("Drawing Blue Circle");
}
}
class RedSquare {
public void draw() {
System.out.println("Drawing Red Square");
}
}
class BlueSquare {
public void draw() {
System.out.println("Drawing Blue Square");
}
}
// 클라이언트 코드
public class Main {
public static void main(String[] args) {
RedCircle redCircle = new RedCircle();
redCircle.draw();
BlueSquare blueSquare = new BlueSquare();
blueSquare.draw();
}
}
문제점
- 클래스 폭발 문제: 색상과 모양의 조합이 많아지면 클래스 수가 기하급수적으로 증가합니다.
- 유연성 부족: 색상이나 모양을 수정하려면 각각의 조합에 대해 코드를 수정해야 합니다.
- 유지보수 어려움: 새로운 색상이나 모양이 추가될 때 모든 조합을 다시 정의해야 합니다.
해결 방법: 브리지 패턴 적용
브리지 패턴은 **기능 계층(추상부)**과 **구현 계층(구체부)**를 분리해 각각 독립적으로 확장할 수 있도록 합니다. 이 패턴을 사용하면 기능의 확장과 구현의 확장이 서로 간섭하지 않습니다.
Implementation 정의
// 색상 인터페이스
interface Color {
String fill();
}
// 구체적인 색상 구현
class Red implements Color {
@Override
public String fill() {
return "Color is Red";
}
}
class Blue implements Color {
@Override
public String fill() {
return "Color is Blue";
}
}
Abstraction 정의
// 모양 추상 클래스
abstract class Shape {
protected Color color; // 구현부와 연결
public Shape(Color color) {
this.color = color;
}
public abstract void draw();
}
구체적인 추상부 구현
// 원 모양 클래스
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("Drawing Circle with " + color.fill());
}
}
// 사각형 모양 클래스
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void draw() {
System.out.println("Drawing Square with " + color.fill());
}
}
클라이언트 코드
public class Main {
public static void main(String[] args) {
// 원을 빨간색으로 그리기
Shape redCircle = new Circle(new Red());
redCircle.draw(); // Drawing Circle with Color is Red
// 사각형을 파란색으로 그리기
Shape blueSquare = new Square(new Blue());
blueSquare.draw(); // Drawing Square with Color is Blue
}
}
브리지 패턴의 장단점
장점
- 확장성: 기능과 구현을 독립적으로 확장할 수 있습니다. 예를 들어, 새로운 색상이나 모양을 추가해도 기존 클래스를 수정할 필요가 없습니다.
- 유지보수 용이: 기능과 구현이 분리되어 있어 각 부분을 쉽게 수정할 수 있습니다.
- 코드 중복 제거: 기능과 구현 계층을 분리하여 중복 코드를 줄일 수 있습니다.
- 의존성 감소: 기능 계층과 구현 계층이 강하게 결합되지 않으므로 결합도가 낮아집니다.
단점
- 복잡성 증가: 추상 계층과 구현 계층을 분리해야 하므로 코드가 복잡해질 수 있습니다.
- 클래스 수 증가: 기능과 구현을 각각 클래스로 정의해야 하므로 클래스의 수가 늘어날 수 있습니다.
결론
브리지 패턴은 기능과 구현을 분리하여 유연성과 확장성을 높이는 데 유용한 패턴입니다. 이 패턴을 사용하면 기능과 구현이 독립적으로 변경될 수 있어 유지보수가 쉬워집니다. 하지만 추상화와 구현을 분리하는 과정에서 코드의 복잡성이 증가할 수 있으므로, 복잡한 기능을 가진 애플리케이션에서 사용하기 적합합니다.