프로그래밍/자바 디자인패턴

디자인 패턴 Bridge 패턴

가카리 2012. 8. 1. 22:02
반응형

Bridge 패턴

기능의 클래스 계층

1. 상위 클래스는 기본적인 기능을 가지고 있다.

2. 하위 클래스에서 새로운 기능을 추가한다.

구현의 클래스 계층

1. 상위 클래스는 추상 메소드에 의해 인터페이스를 규정한다.

2. 하위 클래스는 구상 메소드에 의해 그 인터페이스를 구현한다.

구현은 실제 메소드의 내용을 써내려가는 것이고

기능은 그 메소드를 사용해서 어떠한 것을 수행한다고 생각하면 좋습니다.

 

 

 

Display클래스는 다리의 역활

CountDisplay는 정의된 메소드 가져다가 자기맘대로 덧붙이는 기능 개선하는 역할

DisplayImpl는 메소드의 정의만 만들어둠.

StringDisplayImpl은 메소드를 구현.

Display 클래스

브릿지 패턴의 핵심이 되는 부분입니다. 실제로 다리의 역활을 하는중요한 부분입니다.

package kch;

public class Display {

       

        privateDisplayImpl impl;

       

        //브릿지 패턴처럼 이 Display 클래스가 다리를 놓는다.

        //기능의 클래스 계층(abstract) 구현의 클래스 계층(implement)

        //DisplayImpl는 기능의 클래스 계층입니다.

        publicDisplay(DisplayImpl impl){

               this.impl = impl;

        }

       

        //raw 붙은 것들은 추상클래스 입니다.

        public void open(){

               impl.rawOpen();//rawOpen()

        }

       

        public void print(){

               impl.rawPrint();//rawPrint()

        }

       

        public void close(){

               impl.rawClose();//rawClose()

        }

       

        public final void display(){

               open();

               print();

               close();

        }

}

CountDisplay 클래스

여기서는 추상메소드를 바탕으로 다른 기능을 만듭니다.

package kch;

public class CountDisplay extendsDisplay{

        publicCountDisplay(DisplayImpl impl){

               super(impl);

        }

       

        public void multiDisplay(inttimes){//tiems 반복해서 표시한다

               open();

               for(int i = 0 ; i < times; i++){

                       print();

               }

               close();

        }

}

브릿지에서 사용하는 메소드들은 추상메소드이므로 다음과같은 추상클래스가 필요합니다.

package kch;

public abstract class DisplayImpl {

        public abstract void rawOpen();

        public abstract void rawPrint();

        public abstract void rawClose();

}

StringDisplayImpl은 실제로 추상메소드들을 구현합니다.

package kch;

public class StringDisplayImpl extends DisplayImpl{

       

        /**

         *@uml.property name="string"

         */

        privateString string;

        /**

         *@uml.property name="width"

         */

        private int width;

       

       

        publicStringDisplayImpl(String string){

               this.string= string;//멤버변수에 넣음

               this.width= string.getBytes().length;//스트링을 바이트단위의 길이를 기억해둠.

        }

       

        //실제 추상클래스를 구현하는 부분.

        public void rawOpen(){

               printLine();

        }

       

       

        public void rawPrint(){

               System.out.println( "|" + string + "|");

        }

       

       

        public void rawClose(){

               printLine();

        }

       

       

        private void printLine(){

               //System.out.println(width);

               System.out.print("+");

               for(int i = 0 ; i < width; i++){

                       System.out.print("-");

               }

               System.out.println("+");

        }

       

       

}

메인 클래스입니다.

package kch;

public class Main {

        public static void main(String[] args){

              

               Display d1 = new Display(new StringDisplayImpl("Hello Korea.") );

               //DisplayImpl 클래스는추상클래스여서 위처럼 StringDisplayImpl 클래스로 넘김

               //만약 StringDisplayImpl이 아니고 다른 구현클래스를 넘기면 그 곳에서 구현된

               //것이 넘어가게됨. 즉 구현 클래스를 여러개 할 수 도 있다.

              

              

               Display d2 = new CountDisplay(newStringDisplayImpl("Hello,World"));

              

               CountDisplay d3 = new CountDisplay(newStringDisplayImpl("Hello,Universe"));

              

               d1.display();//1회 출력

               d2.display();//1회 출력원하면 카운터 기능도 사용가능

               d3.display();//1회 출력

               d3.multiDisplay(5);//5회 출력

        }

}

결론적으로 잘 가져가서 쓰는놈 따로있고 구현하는놈 따로 있다.가 되겠습니다.

 

결과 화면

 

 

 

 

브릿지 패턴의 특징은 기능 클래스 계층과 구현 클래스 계층을 분리한 것인데 이 계층을 분리해두면 언젠가 기능을추가로 넣거나 구현을 바꿀 때 독립적으로 할 수 있습니다.

예를들어 윈도우판 맥용, 유닉스용이 분리되면 세 운영체제의 공통의인터페이스(추상클래스)만 정해서 구현클래스(StringDisplayImpl)만 다르게 수정하면 세 운영체제에 맞게 구현이 가능합니다.

이렇게 구현하면 어떤 기능은 세 운영체제에서 동일하게 됩니다.

 

 

반응형