본문 바로가기

Computer Science/Design Pattern

[Design Pattern] 브릿지 패턴(Bridge Pattern)에 대해서 - 컴도리돌이

728x90

class Circle {
    void drawWithRedColor() {
        // 빨간색 원 그리기
    }

    void drawWithBlueColor() {
        // 파란색 원 그리기
    }
}

class Square {
    void drawWithRedColor() {
        // 빨간색 사각형 그리기
    }

    void drawWithBlueColor() {
        // 파란색 사각형 그리기
    }
}

 

이 코드에서 CircleSquare 클래스는 각각 빨간색과 파란색으로 도형을 그리는 메서드를 가지고 있어요. 지금은 두 가지 도형과 색상만 다루고 있죠.

그런데 여기서 도형의 종류가 더 늘어나면 어떻게 될까요? 또는 색상이나 그리기 방식이 더 다양해지면 어떨까요? 🤔

'아, 그냥 도형 클래스에 색상 속성을 추가하고 메서드를 더 만들면 되지!'라고 생각할 수도 있어요. 실제로 이렇게 하는 게 간단하고, 유지보수도 그다지 어렵지 않을 수 있죠.

하지만, 만약 그려야 할 도형이 원, 삼각형, 정사각형, n각형 등으로 늘어나고, 각각의 도형마다 빨강, 노랑, 초록, 파랑 같은 색상을 추가해야 한다면? 조합이 늘어날수록 필요한 클래스도 기하급수적으로 늘어나는 걸 상상해 보세요. 😔

그러면 어떻게 될까요? 당연히 코드가 급격하게 늘어나고, 복잡해지며 유지보수가 어려워지겠죠... 😠


브릿지 패턴(Bridge Pattern)

브릿지 패턴은 도형과 색상을 분리해, 서로 독립적으로 확장할 수 있도록 도와줍니다. 예를 들어, 원과 사각형 같은 도형이 있고, 빨강과 파랑 같은 색상 클래스가 있다고 가정해 볼게요. 브릿지 패턴의 핵심은 바로 이 두 개의 요소를 조합해 주는 역할을 한다는 거예요.

 

이렇게 되면, "원을 빨강로 칠하고, 사각형을 파란색으로 칠하는" 식으로 자유롭게 조합할 수 있습니다. 새로운 색상을 추가하더라도 기존 도형 클래스는 수정할 필요가 없고, 새로운 색상 클래스를 추가하기만 하면 되니 확장이 훨씬 쉬워지는 거죠. 😎

 

interface Color {
    void applyColor();
}

 

Color 인터페이스는 색상을 적용하는 메서드인 applyColor()를 정의합니다. 이 인터페이스는 브릿지 패턴에서 구현 계층의 역할을 맡고 있어요. 구체적인 색상 구현 클래스들이 이 인터페이스를 구현하게 될 거예요.

 

이 인터페이스를 사용하면 다양한 색상 클래스를 동일한 방식으로 처리할 수 있습니다. Shape 클래스는 특정 색상 클래스에 종속되지 않도록 되어 있으며, 새로운 색상을 추가할 때도 이 인터페이스만 구현하면 되기 때문에 유연성을 제공하죠. 😊

 

class RedColor implements Color {
    @Override
    public void applyColor() {
        System.out.println("Applying red color");
    }
}

class BlueColor implements Color {
    @Override
    public void applyColor() {
        System.out.println("Applying blue color");
    }
}

 

이제 Color 인터페이스를 구현한 구체적인 색상 클래스를 살펴볼까요? RedColorBlueColor 클래스는 각각 빨강과 파랑으로 도형에 색을 입힐 수 있습니다. 브릿지 패턴에서 구체적인 구현은 인터페이스를 통해 분리되며, 이 클래스들은 applyColor() 메서드를 오버라이드하여 자신만의 색상 적용 방식을 정의합니다.

 

새로운 색상을 추가할 때는, 이제 이 패턴을 확장하여 새로운 Color 구현체를 만들기만 하면 되죠! 확장성이 뛰어나죠?

 

abstract class Shape {
    protected Color color;

    protected Shape(Color color) {
        this.color = color;
    }

    abstract void draw();
}

 

Shape 클래스는 브릿지 패턴에서 추상화 계층의 역할을 합니다. 도형과 색상 간의 관계를 분리해, 도형의 종류와 색상을 독립적으로 확장할 수 있도록 해주죠. 이 구조 덕분에, 계층 구조의 복잡성이 줄어들게 됩니다.

 

코드를 보면, Shape 클래스는 Color 타입의 참조 변수를 가지고 있고, 이를 통해 색상과 관련된 작업을 위임할 수 있어요. 그리고 draw() 메서드는 구체적인 도형 클래스에서 구현해야 할 추상 메서드로 정의되어 있습니다.

 

class Circle extends Shape {
    protected Circle(Color color) {
        super(color);
    }

    @Override
    void draw() {
        System.out.print("Circle drawn. ");
        color.applyColor();
    }
}

 

마지막으로, Shape 클래스를 상속한 CircleSquare 클래스를 보면, 각각의 도형이 어떻게 그려져야 하는지를 정의합니다. 이 클래스들은 Shape 클래스에서 정의된 추상 메서드 draw()를 구체적으로 구현해, 도형의 종류에 따라 추가적인 기능을 제공할 수 있죠.

 

이렇게 브릿지 패턴을 적용하면, 도형과 색상을 독립적으로 관리하면서도 필요한 조합을 자유롭게 만들어낼 수 있어요. 도형이 늘어나거나 색상이 추가되더라도 기존 코드를 크게 변경하지 않아도 되기 때문에, 유지보수와 확장에 강력한 장점을 제공합니다. 💪


전략 패턴에 대해서

그렇지만, 단순히 "원에 빨간색, 사각형에는 파란색" 정도만 필요한 상황에서도 브릿지 패턴을 쓰는 게 과연 맞을까요?

 

괜히 더 복잡해질 것 같다는 생각이 들지 않나요? 정말 간단한 작업에 불필요하게 인터페이스나 추상 클래스를 만들고, 이것저것 연결하다 보면 코드가 오히려 복잡해지고 읽기 어려워질 수 있어요.

 

이럴 때는 차라리 전략 패턴을 사용하는 게 더 나을 수 있어요. 전략 패턴은 "도형을 그리는 전략"을 하나의 클래스로 캡슐화하고, 필요할 때 그 전략을 바꿔치기하는 방식이죠. 예를 들어, "빨간색 원 그리기"라는 전략과 "파란색 사각형 그리기"라는 전략을 만들어서, 그때그때 필요한 전략을 선택해서 사용하는 식이에요. 🤔

 

 

[Design Pattern] 전략 패턴(Strategy Pattern)에 대해서 - 컴도리돌이

여러 방식으로 기능이 작동되는 메서드에서, 또 다른 기능을 추가해야 할 경우 어떻게 해야 할까요? 🤔 코드 형태에 따라 구현 방식이 천지 차이지만, if-else로 분기를 태워서 한 메서드에서 서

comdolidol-i.tistory.com

 

interface DrawingStrategy {
    void draw();
}

class RedCircleDrawing implements DrawingStrategy {
    @Override
    public void draw() {
        System.out.println("Drawing a red circle");
    }
}

class Shape {
    private DrawingStrategy strategy;

    public Shape(DrawingStrategy strategy) {
        this.strategy = strategy;
    }

    public void draw() {
        strategy.draw();
    }
}

 

 

 

 

이 방법은 구조를 단순하게 유지하면서도, 새로운 전략을 추가하기가 쉬워집니다. 클래스 계층이 깊어지지 않고, 각 전략이 독립적이기 때문에 코드가 훨씬 깔끔해질 수 있겠죠!

 

결론적으로, 브릿지 패턴을 사용할지 말지 결정할 때는 "이게 정말 필요한 복잡성인가?"를 꼭 생각해봐야 할 것 같아요. 🤔 조합이 많고, 계속 확장될 가능성이 높다면 브릿지 패턴이 좋은 선택이 될 수 있지만, 단순한 상황이라면 전략 패턴처럼 더 직관적이고 간단한 방법이 더 나을 수 있을 거예요. 😊