본문 바로가기
까망 동네/디자인 패턴

[디자인 패턴] 브릿지 패턴 (Bridge Pattern)

by 까망 하르방 2023. 10. 28.
반응형

🎈 브릿지 패턴 (Bridge Pattern) 

• 새로운 인터페이스를 정의하여

 기존 프로그램 변경없이 기능 확장할 수 있다.

• 기능을 독립적으로 확장할 수 있다면

 상세한 기능을 외부로부터 숨길 수 있는 은닉 효과도 얻을 수 있다.

• 디자인 패턴 중에서 구조 패턴에 해당한다.

 

💻 디자인 패턴(Design Pattern)이란?

👨‍💻 디자인 패턴(Design Pattern)이란? • SW 개발 방법 중에서도 구조적인 문제 해결에 목적을 둔다. • 알고리즘과 같이 특정 문제를 해결하는 Logic 형태보다는 특정 상황에 적용할 수 있는 방

zoosso.tistory.com


 

[예제 코드]

#include <iostream>

// 추상 구현 클래스
class Implementor {
public:
    virtual void operationImpl() = 0;
};

class ConcreteImplementor : public Implementor {
public:
    void operationImpl() override {
        std::cout << "구현 클래스" << std::endl;
    }
};

// 추상화 클래스
class Abstraction {
public:
    Abstraction(Implementor* impl) : implementor(impl) {}

    virtual void operation() {
        implementor->operationImpl();
    }

protected:
    Implementor* implementor;
};


class RefinedAbstraction : public Abstraction {
public:
    RefinedAbstraction(Implementor* impl) : Abstraction(impl) {}

    void additionalOperation() {
        std::cout << "확장 추상화 클래스" << std::endl;
    }
};

void main() {
    Implementor* impl = new ConcreteImplementor();

    RefinedAbstraction* abstraction = new RefinedAbstraction(impl);

    abstraction->operation();
    abstraction->additionalOperation();
}

 

디자인패턴 브릿지 패턴 예시

AbstractionImplementor 사이의 브릿지를 통해

서로 독립적으로 확장할 수 있게 하였다.


 

🎈 브릿지 패턴 장단점

+ 구현과 추상화 분리: 독립적으로 확장하거나 수정 가능

+ 다중 플랫폼 지원하는 코드 개발시 유용하다.

 

- 복잡성 증가: 하나의 클래스를 (추상 + 구현) 계층으로 분리하기에

 규모가 작은 프로젝트에서는 복잡해지는 편이다.

 

[예제 코드] - 브릿지 패턴 적용 X

#include <iostream>

// 모양을 나타내는 클래스
class Shape {
public:
    virtual void draw() = 0;
};

// 구체적인 모양 클래스 - 원
class Circle : public Shape {
public:
    void draw() override {
        std::cout << "원을 그립니다." << std::endl;
    }
};

// 구체적인 모양 클래스 - 사각형
class Rectangle : public Shape {
public:
    void draw() override {
        std::cout << "사각형을 그립니다." << std::endl;
    }
};

void main() {
    Shape* circle = new Circle();
    Shape* rectangle = new Rectangle();


    circle->draw();
    rectangle->draw();
}

 

디자인패턴 브릿지 패턴 예시

클래스를 상속하면 구현과 추상 개념이 결합이 강하다.

이 경우 상속 클래스를 수정하거나 확장하기 어려워진다.

override 하여 재정의하여도 부모 클래스의 메서드를 모두 포함해야 한다.

상속으로 계속 기능을 확장하며 최종 클래스는 무거워진다.

 

 

[예제 코드] - 브릿지 패턴 적용

모양(Shape)과 그림 그리기 방식(DrawingAPI)을 분리

느슨한 결합으로 다양한 모양과 구현 방식을 조합할 수 있다.

#include <iostream>

// 구현 방식을 나타내는 인터페이스
class DrawingAPI {
public:
    virtual void drawShape() = 0;
};

// 구체적인 구현 방식 - 원
class CircleDrawingAPI : public DrawingAPI {
public:
    void drawShape() override {
        std::cout << "원을 그립니다." << std::endl;
    }
};

// 구체적인 구현 방식 - 사각형
class RectangleDrawingAPI : public DrawingAPI {
public:
    void drawShape() override {
        std::cout << "사각형을 그립니다." << std::endl;
    }
};

// ------------------------------------------

class Shape {
public:
    virtual void draw() = 0;
};

// 모양 클래스와 구현 방식을 연결
class Circle : public Shape {
public:
    Circle(DrawingAPI* drawingAPI) : drawingAPI(drawingAPI) {}


    void draw() override {
        drawingAPI->drawShape();
    }

private:
    DrawingAPI* drawingAPI;
};

class Rectangle : public Shape {
public:
    Rectangle(DrawingAPI* drawingAPI) : drawingAPI(drawingAPI) {}


    void draw() override {
        drawingAPI->drawShape();
    }

private:
    DrawingAPI* drawingAPI;
};

// ------------------------------------------

void main() {
    CircleDrawingAPI circleAPI;
    RectangleDrawingAPI rectangleAPI;

    Circle circle(&circleAPI);
    Rectangle rectangle(&rectangleAPI);

    circle.draw();
    rectangle.draw();
}

 

🎈 브릿지 패턴 활용

• 그래픽 라이브러리: 그래픽 요소와 출력 장치 연결

• 데이터베이스 연결: 다른 DBMS 연결 지원

• 리모컨 및 기기 컨트롤: 다양한 기기간 연결 관리

 

[예제 코드] - 브릿지 패턴 적용 전

#include <iostream>
#include <string>

// Book 클래스
class Book {
public:
    Book(const std::string& title, const std::string& author)
        : title(title), author(author) {}


    void print() {
        std::cout << "Title: " << title << std::endl;
        std::cout << "Author: " << author << std::endl;
    }

private:
    std::string title;
    std::string author;
};

void main() {
    Book book("디자인 패턴", "까망 하르망");
    book.print();
}

 

디자인패턴 브릿지 패턴 예시

 도서 관리시스템으로 간단하게 책(Book)과 출력(Printer) 기능이 있다.

 

 

예제 코드] - 브릿지 패턴 적용 후

#include <iostream>
#include <string>


// 출력 인터페이스
class Printer {
public:
    virtual void print(const std::string& content) = 0;
};

// 구체적인 출력 클래스 - 화면에 출력
class ScreenPrinter : public Printer {
public:
    void print(const std::string& content) override {
        std::cout << "Screen Output: " << content << std::endl;
    }
};

// 구체적인 출력 클래스 - 프린터로 출력
class PrinterPrinter : public Printer {
public:
    void print(const std::string& content) override {
        std::cout << "Printer Output: " << content << std::endl;
    }
};

// Book 클래스
class Book {
public:
    Book(const std::string& title, const std::string& author, Printer* printer)
        : title(title), author(author), printer(printer) {}


    void print() {
        printer->print("Title: " + title);
        printer->print("Author: " + author);
    }

private:
    std::string title;
    std::string author;
    Printer* printer;
};


void main() {
    ScreenPrinter screenPrinter;
    PrinterPrinter printerPrinter;

    Book book1("디자인 패턴", "까망 하르망", &screenPrinter);
    Book book2("디자인 패턴", "까망 하르망", &printerPrinter);

    book1.print();
    book2.print();
}

 

디자인패턴 브릿지 패턴 예시

Printer 인터페이스로 출력 방식을 경정할 수 있다.

이로인해 Book 클래스는 수정하지 않아도

다양한 출력 방식을 지원할 수 있다.


🎈 다른 디자인 패턴과 비교

• 어댑터 (Adapter)

Bridge 패턴과 마찬가지로 인터페이스를 조정한다.

하지만 어댑터 패턴은 호환되지 않는 인터페이스를

가능하도록 인터페이스로 변환하는 것에 차이가 있다.

 

또한, 어댑터 패턴이 완성된 코드를 결합하는 것이라면

브릿지 패턴은 설계 단계에서 확장을 고려해서 추상화 하는 것이다.

 

[디자인패턴] 어댑터 패턴 (Adapter Pattern)

🎈 어댑터 패턴 (Adapter Pattern) • 호환되지 않는 인터페이스를 가진 두 개의 클래스를 함께 사용할 수 있게 한다. • 상속 보다는 위임하는 형태 권장 상속은 실수로라도 접근할 수 있기에 데이

zoosso.tistory.com

 

 

• 전략 (Strategy)

객체 간의 관계를 느슨하게 만들지만 목적과 사용 시점이 다르다.

브릿지 패턴은 주로 추상화와 구현을 분리하여

복잡한 클래스 계층 구조를 간소화하여 새로운 기능을 쉽게 추가/변경 한다.

반면에 전략 패턴은 알고리즘을 분리하여 Rumtime에 선택할 수 있게 한다.

 

💻 [디자인패턴] 전략 패턴 (Strategy Pattern)

전략 패턴 (Strategy Pattern) 이란? 전략(Strategy)은 코드 내부에서 로직(Logic)을 처리하는 「알고리즘」 어떤 목적 달성을 위한 수행 방식이라고 생각하면 좋다. 영화관에서 이벤트 영화 예매 방식을

zoosso.tistory.com

 

 

• 장식자 (Decorator)

데코레이터 패턴과는 구조적인 측면에서 다르다.

데코레이터 패턴이 Runtime에 객체 동작을 변경/확장할 수 있고

브릿지 패턴은 추상화와 구현을 분리해서 계층 구조를 관리하는데 중점을 둔다.

 

[디자인패턴] 장식자 패턴 (Decorator)

🎈 데코레이터 패턴 (Decorator Pattern) • 객체에 동적으로 기능을 추가하거나 변경할 수 있게 해주는 패턴 • 압축, 암호화, 버퍼링 기능 추가시 활용해볼 수 있다. • 디자인 패턴 중 구조 패턴에

zoosso.tistory.com

반응형

댓글