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

디자인 패턴 Builder 패턴

가카리 2012. 8. 1. 21:59
반응형

Builder 패턴

 

어떤 건물을 지을때 아래에서 위로 조금씩 만들어가는 것처럼 구조를 가진 인스턴스를 쌓아올리는 것을 하는 패턴입니다.

 

예제는 5개의 클래스가 나옵니다.

 

Builder 문서를 구성하기 위한 메소드를 결정하는 추상 클래스

Director 한 개의 문서를 만드는 클래스

TextBuilder 일반 텍스트를 이용해서 문서를 만드는 클래스

HTMLBuilder HTML 파일을 이용해서 문서를 만드는 클래스

Main 동작 테스트용 클래스

 

 

 

Builder.java

 

public abstract class Builder {//건물의 파트 벽돌 시멘트 철근 같을 것을 추상화함

       //구체적으로는 아니고 이런 재료만 것이다 이런 구체적으로는 상속받은 클래스가

       public abstract void makeTitle(String title);//타이틀

       public abstract void makeString(String str);//문자열

       public abstract void makeItems(String[] items);//개별항목을 문서안에서 구축하는 메소드

       public abstract void close();

}

 

 

Director.java

 

 

public class Director {

       //건물을 어떻게 지을지?

       //땅파고 철근넣고 콘크리트 넣고 그런 순서를 클래스가 정해줌

       /**

        * @uml.property name="builder"

        * @uml.associationEnd multiplicity="(1 1)"

        */

       private Builder builder;

       public Director(Builder builder){

             this.builder = builder;

       }

 

       public void construct(){//건물 짓는 순서를 말함

             builder.makeTitle("Greeting");//타이틀

             builder.makeString("아침과 낮에");//문자열

             builder.makeItems(new String[]{

                           "좋은 아침입니다.",

                           "안녕하세요."

             });

             builder.makeString("밤에");//별도의 문자열

             builder.makeItems(new String[]{//별도의 개별 항목

                    "안녕하세요.",

                    "안녕히 주무세요.",

                    "안녕히 계세요."

             });

             builder.close();//문서를 완성시킨다.

            

       }

}

 

 

 

TextBuilder.java

 

 

public class TextBuilder extends Builder{

       //건물을 지을때 어떤 벽돌을 쓸것이고 어떤 회사의 시멘트를 쓸것이고 재료들을 구체화함

       /**

        * @uml.property name="buffer"

        */

       private StringBuffer buffer = new StringBuffer();//버퍼를 가지고있는 String이라고 표현하면 좋을

      

       @Override

       public void close() {//문서의 완성

             // TODO Auto-generated method stub

             buffer.append("==========================\n");

       }

 

       @Override

       public void makeItems(String[] items) {

             // TODO Auto-generated method stub

             for(int i = 0; i < items.length; i++){

                    buffer.append(" -" + items[i] + "\n");

             }

            

             buffer.append("\n");

       }

 

       @Override

       public void makeString(String str) {//일반 텍스트에서의 문자열

             // TODO Auto-generated method stub

             buffer.append('*' + str + "\n");

             buffer.append("\n");

       }

 

       @Override

       public void makeTitle(String title) {//일반 텍스트의 제목

             // TODO Auto-generated method stub

             buffer.append("================\n");//스트링을 추가한다는 append 덧붙이다라는 뜻임

             buffer.append("\"" + title + "\"");

             buffer.append("\n");

       }

      

       public String getResult(){//완성했으면 buffer내용을 꺼내서 보냄

             return buffer.toString();

       }

 

}

 

 

HTMLBuilder.java

 

import java.io.FileWriter;

import java.io.IOException;

import java.io.PrintWriter;

 

 

public class HTMLBuilder extends Builder{

       //건물을 지을때 빨강 벽돌을 쓸것인가 검은 벽돌을 쓸것인가 어떤 회사의 시멘트를 것인가 재료들을 구체화함

       /**

        * @uml.property name="filename"

        */

       private String filename;

       /**

        * @uml.property name="writer"

        */

       private PrintWriter writer;//파일에 기술을 위해서

      

       @Override

       public void close() {

             // TODO Auto-generated method stub

             writer.println("</body></html>");

             writer.close();

       }

 

       @Override

       public void makeItems(String[] items) {

             // TODO Auto-generated method stub

             writer.println("<u1>");

             for(int i = 0; i < items.length ; i++){

                    writer.println("<li>" + items[i] + "</li>");

             }

             writer.println("</ul>");

            

       }

 

       @Override

       public void makeString(String str) {//HTML파일에서의 문자열

             // TODO Auto-generated method stub

             writer.println("<p>" + str + "</p>");//<p>태그로 출력

            

       }

 

       @Override

       public void makeTitle(String title) {

             // TODO Auto-generated method stub

             filename = title + ".html";

             try{

                    writer = new PrintWriter(new FileWriter(filename));//PrintWriter 만든다

             }catch(IOException e){

                    e.printStackTrace();//예외 발생시..

             }

            

             writer.println("<html><head><title>" + title + "</title></head><body>");//타이틀을 출력

             //html형식입니다. 저도 초등학교 이후로 보는 구문이라서 익숙치가 않네요

             writer.println("<h1>" + title + "</h1>");           

       }

 

       public String getResult(){

             return filename;

       }

}

 

 

 

 

Main.java

 

public class Main {

 

       /**

        * @param args

        */

       public static void main(String[] args) {

             // TODO Auto-generated method stub

 

             if(args.length != 1){

                    usage();

                    System.exit(0);

             }

            

             if(args[0].equals("plain")){

                    TextBuilder textbuilder = new TextBuilder();//구체적인 재료들을 만들어주고

                    Director director = new Director(textbuilder);//건축 설계자한테 재료를 넘겨주면

                    director.construct();//건축 설계자가 재료들로 어떤 순서로 지을것인지 말을 해줌

                    String result = textbuilder.getResult();//결과는 getResult 받아옵니다

                    System.out.println(result);

             }else if(args[0].equals("html")){

                    HTMLBuilder htmlbuilder = new HTMLBuilder();

                    Director director = new Director(htmlbuilder);

                    director.construct();//위와 마찬가지인데 결과는 html파일입니다.

                    String filename = htmlbuilder.getResult();

             }else{//잘못 입력됬다면

                    usage();

                    System.exit(0);

             }

       }

 

       public static void usage(){//그냥 에러메시지

             System.out.println("Usage : plain 일반 텍스트로 문서작성");

             System.out.println("Usage : html HTML파일로 문서작성");

       }

}

 

 

 

 

 

Run configulation에서 Main의 인자를 plain으로 주고 해보겠습니다.

 

 

 

 

결과는 다음과 같습니다.

 

 

 

 

똑같이 html으로도 해보고 프로젝트 파일에 들어가보면 Greeting.html파일이 있습니다. 실행해보면

 

 

이 패턴의 가장 중요한점은 Director는 실제로 동작하는 것이 TextBuilder인지 HTMLBuilder인지 모른다는 점입니다. 즉 건축 설계자는 그냥 재료만 주면 어떻게 만들지 정해준다는 것입니다.(어떤 회사 벽돌인지 어떤 회사 시멘트인지는 중요하지않음)

 

이점이 왜 중요하면 Director가 모르기 때문에 몰래 재료를 바꾸는 것이 가능하다는 소리입니다.(몰래 값싼 재료 써도 됨!)

 

 

 

반응형