본문 바로가기

Programming/과거포스팅

Bridge pattern (브릿지 패턴)


이번 장은 브릿지(Bridge)패턴이다


다리?? 무언가를 연결해주는 패턴인가라고 생각할 수 있을것이다.

브릿지 패턴이란 무엇일까?


위키를 보면 

브리지 패턴(Bridge pattern)이란 구현부에서 추상층을 분리하여 각자 독립적으로 변형할 수 있게 하는 패턴이다. 

이렇게 나와있다. 이것만 보면 이해하기 힘들것이다


특히 나같은 초급개발자는 이해하기가 힘들것이다.

좀더 자세히 알아보자

브릿지 패턴은 소프트웨어 공학에서 사용되는 디자인 패턴이다.

구현(implementation)으로부터 추상(abstraction) 레이어를 분리하여 독립적으로 변형할 수 있게 하는 패턴이다.


이제 우리에게 익숙한 말들이 나오기 시작했다.

우리가 흔히 사용하는 interface에서 abstract를 분리하겠다는 내용인데. 어떻게 분리하고 분리함으로써 얻을 수 있는 장점은 무엇인지

알아보자


위키랑 여러 사이트들에서 자료를 찾다보니 어느정도 감이 잡혔다.

브릿지 패턴은 추상화의 두 계층으로 생각할 수 있다.

구현을 담당하는 interface와 기능을 담당하는 abstraction


나는 실무에서 이런식으로 나눠본적이 없는데 브릿지 패턴을 공부하면서 적절한 곳에 사용하면 아주 유용할거 같다는 생각을 하게 되었다.

구현부를 interface로 가지고 이 interface를 implements하는 abstract 클래스를 작성한다.

그리고 기능을 담당할 method를 작성한다. 그러면 구현을 담당하는 메서드는 모든 클래스가 공통으로 가지며

기능부분은 이 interface를 implements 하는 abstract클래스에서 작성한다.

그러면 기능을 구현부로부터 완전히 분리할 수 있을 뿐만 아니라 확장에도 용이하다.


간단한 코드를 이용해서 확인해보자

검색을 해보니 도형그리기 예가 많았고 아주 적절한 예인거 같다. 

실무코드들은 너무 양이 많아서 예제 코드로 대신 하는것 양해 바람.

아래 코드를 활용해서 브릿지 패턴의 예만 확인하자 한가지 패턴만 적용해서 코드를 구현하다보면

깔끔하지 못하는 경우가 많다.

좋은 코드를 작성하기 위해선 필요한 패턴을 여러개를 적용해야 하는 경우도 많이 있다.

아래는 도형을 그리는 코드이다.


package com.study; interface BaseDrawing { //베이스 인터페이스를 생성한다, 위의 설명대로 구현부이다. 원과, 사각형의 구현을 선언한다. public void drawCircle(double x, double y, double radius); public void drawRect(double x, double y, double width, double height); } class Drawing implements BaseDrawing { //구현부 처리부분이다. 구현부를 분리하여 처리를 할 수있고 지금은 단일이지만 여러 클래스로 확장이 가능하다. @Override public void drawCircle(double x, double y, double radius) { System.out.printf("drawCircle %f,%f radius %f\n", x, y, radius); } @Override public void drawRect(double x, double y, double width, double height) { System.out.printf("drawRect %f,%f width %f height %f\n", x, y, width, height); } } abstract class BaseShape { // 기능부이다. abstract클래스이며 각각의 기능에 대해서 정의한다. 기능부를 생성시점에 받도록 작성하였다. protected BaseDrawing baseDrawing; protected BaseShape(BaseDrawing baseDrawing) { this.baseDrawing = baseDrawing; } public abstract void draw(); public abstract void resizeByPercentage(double pct); public abstract void setWidth(double width); public abstract void setHeight(double height); } class CircleShape extends BaseShape { 기능부를 상속받아 기능을 구현한 원타입의 도형 private double x, y, radius; public CircleShape(double x, double y, double radius, BaseDrawing baseDrawing) { super(baseDrawing); this.x = x; this.y = y; this.radius = radius; } @Override public void draw() { baseDrawing.drawCircle(x, y, radius); } @Override public void resizeByPercentage(double pct) { radius *= pct; } @Override public void setWidth(double width) { } @Override public void setHeight(double height) { } } class RectShape extends BaseShape { 기능부를 상속받아 기능을 구현한 사각형 타입의 도형 private double x, y, width, height; public RectShape(double x, double y, double width, double height, BaseDrawing baseDrawing) { super(baseDrawing); this.x = x; this.y = y; this.width = width; this.height = height; } @Override public void draw() { baseDrawing.drawRect(x, y, width, height); } @Override public void resizeByPercentage(double pct) { } @Override public void setWidth(double width) { this.width = width; } @Override public void setHeight(double height) { this.height = height; } } class MainClass { // 메인클래스 public static void main(String[] args) { BaseShape baseCircleShape= new CircleShape(1, 2, 30, new Drawing()); baseCircleShape.draw(); BaseShape baseRectShape= new RectShape(1, 2, 30, 40, new Drawing()); baseRectShape.draw(); } }

이와 같이

브릿지 패턴을 사용하면 기능부와 구현부를 분리함으로써 

확장설계에 아주 용이하게 사용할 수 있고

이브릿지패턴의 아주좋은 예가 드라이버다.


앞으로 설계에 유용하게 사용할 수 있을거 같다.