추상을 구현으로부터 분리하여 독립적으로 변하게 하는 패턴이다. 추상과 구현이 헷갈릴수도 있지만 추상은 로직을 정의하는 부분, 구현부는 추상부에서 정의한 연산을 실제로 구현하는 부분이다.
Shape
객체의 모양은 Circle
과 Square
가 있고 색깔에는 Red
와 Blue
가 있다.
1. 여러 모양(Circle, Square)과 색깔을 포함하는 Shape객체가 있다고 하자.
abstract class Shape {
abstract void draw();
}
2. 사각형에는 빨간색(Red)과 파란색(Blue)이 있다.
class RedSquare extends Shape {
void draw() {
System.out.println("Drawing a red square");
}
}
class BlueSquare extends Shape {
void draw() {
System.out.println("Drawing a blue square");
}
}
3. 원에도 빨간색(Red)과 파란색(Blue)이 있다.
class RedCircle extends Shape {
void draw() {
System.out.println("Drawing a red circle");
}
}
class BlueCircle extends Shape {
void draw() {
System.out.println("Drawing a blue circle");
}
}
4. 새로운 색깔인 노란색(Yellow)이 추가됐다고 하면 노란색 사각형과 노란색 원이 추가되어야 한다.
class YellowSquare extends Shape {
void draw() {
System.out.println("Drawing a yellow square");
}
}
class YellowCircle extends Shape {
void draw() {
System.out.println("Drawing a yellow circle");
}
}
5. 새로운 모양인 삼각형(Triangle)이 추가됐다고 하면 빨간색, 파란색, 노란색 삼각형을 추가해야 한다.
class RedTriangle extends Shape {
void draw() {
System.out.println("Drawing a red triangle");
}
}
class BlueTriangle extends Shape {
void draw() {
System.out.println("Drawing a blue triangle");
}
}
class YellowTriangle extends Shape {
void draw() {
System.out.println("Drawing a yellow triangle");
}
}
위 문제상황은 다음과 같다.
빨간색 원
을 그리려 하지 말고,원
을빨간색
으로 그리도록 하자!
모양
과색깔
을 분리하자!
위 문제상황에 브릿지 패턴을 적용한 코드는 다음과 같다.
1. Color
interface Color {
void applyColor();
}
class Red implements Color {
public void applyColor() {
System.out.println("red");
}
}
class Blue implements Color {
public void applyColor() {
System.out.println("blue");
}
}
구현부인 Color인터페이스와 실제 구현하는 Red, Blue클래스
2. Shape
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
abstract void draw();
}
class Square extends Shape {
public Square(Color color) { bsuper(color); }
public void draw() {
System.out.print("Drawing square in ");
color.applyColor();
}
}
class Circle extends Shape {
public Circle(Color color) { super(color); }
public void draw() {
System.out.print("Drawing circle in ");
color.applyColor();
}
}
추상부인 Shape클래스와 이를 재정의한 Square, Circle클래스이다. Shape클래스는 추상클래스인 것을 확인하자.
브릿지 패턴은 Aggregation으로 Color에 대한 레퍼런스를 Shape가 가지고 있다. 이것을 상속관계로 표현할 수 있는데 상속을 이용한것과 집합을 이용한 것은 어떤 차이가 있을까?
상속 | 집합 |
---|---|
실행 시 구현객체 하나만 존재한다. | 실행 시 추상객체와 구현객체가 존재한다. |
컴파일 시 고정된다. | 추상객체와 구현객체의 연결이 런타임에 바뀔 수 있다. |
상속을 이용하면 하나의 객체를 유지할 수 있다는 장점이 있지만 추상부와 구현부를 교체할 수 없다는 단점이 있다.
런타임에 추상부와 구현부가 바뀌지 않는다는 상황이 보장된다면? 상속이 더 효율적인가?