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가 모르기 때문에 몰래 재료를 바꾸는 것이 가능하다는 소리입니다.(몰래 값싼 재료 써도 됨!)

 

 

 

블로그 이미지

가카리

소프트웨어와 하드웨어 프로그래밍, 취업 및 직장생활 전문 블로그