2015년 10월 16일 금요일

클래스 디자인 패턴 14. Builder

1. 개념
   구조를 가지는 인스턴스를 쌓아 올리는 Builder 패턴
 
 



2. 소스

  1) 문서를 생성하는 기능을 작성하고자 하는데 여기서
     문서의 메서드를 강제하는 Builder abstract Class 를 생성


public abstract class BuilderO {
public abstract void makeTitle(String titile);
public abstract void makeString(String str);
public abstract void makeItems(String[] items);
public abstract Object getResult();
}


  2) bulder를 사용하는 Director를 작성

public class Director {
private BuilderO builder;

public Director(BuilderO builder){
this.builder = builder;
}

public Object construct(){
builder.makeTitle("Greeting");
builder.makeString("morning and afternoon");
builder.makeString("at night");
builder.makeItems(new String[]{
"Hello",
"good night",
"see you late"});
return builder.getResult();
}
}


  3) builder를 상속하여 작성하는 첫번째 텍스트 빌더를생성

public class TextBuilder extends BuilderO {
private StringBuffer buffer = new StringBuffer();

@Override
public void makeTitle(String title) {
buffer.append("========================\n");
buffer.append("┌"+title +"┘\n");
buffer.append("\n");
}

@Override
public void makeString(String str) {
buffer.append("■"+str+"\n");
buffer.append("\n");
}

@Override
public void makeItems(String[] items) {
for(int i=0; i<items.length;i++){
buffer.append("~"+items[i]+"\n");
}
buffer.append("\n");
}

@Override
public Object getResult() {
buffer.append("======================");
return buffer.toString();
}

}


  4) 역시 builder를 상속받아 작성하는 html 빌더를 작성
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;


public class HtmlBuilder extends BuilderO {
private String filename;
private PrintWriter writer;
@Override
public void makeTitle(String title) {
filename = title +".html";
try{
writer = new PrintWriter(new FileWriter(filename));
}catch(IOException e){
e.printStackTrace();
}
writer.println("<html><head><title>"+title+"</title></head><body>");
writer.println("<h1>"+title+"</h1>");
}

@Override
public void makeString(String str) {
writer.println("<p>"+str+"</p>");
}

@Override
public void makeItems(String[] items) {
writer.println("<ul>");
for(int i=0; i<items.length;i++){
writer.println("<li>"+items[i]+"</li>");
}
writer.println("</ul>");

}

@Override
public Object getResult() {
writer.println("</body></html>");
writer.close();
return filename;
}

}


  5) 테스트 클래스를 작성
public class MainTest {
public static void main(String[] args) {
if(args.length !=1){
usage();
System.exit(0);
}

if(args[0].equals("plain")){
Director director = new Director(new TextBuilder());
String result = (String) director.construct();
System.out.println(result);
}else if(args[0].equals("html")){
Director director = new Director(new HtmlBuilder());
String filename = (String) director.construct();
System.out.println(filename + "이 작성되었습니다.");
}else{
usage();
}
}

private static void usage() {
System.out.println("Usage : java main plain ");
System.out.println("Usagfe : java main html ");
}
}


결과 1 :  main 의 인자로들어가는 argument str[] 에
         옵션을 줘야지만 정상적인 테스트가 가능함

     run 에 argument 로 plain 부여시
========================
┌Greeting┘

■morning and afternoon

■at night

~Hello
~good night
~see you late

======================

결과 2 : run 옵션 argument 에 html 부여시

Greeting.html이 작성되었습니다.

and
프로젝트 페이지에 다음 파일이 생성됨
그리고 해당 파일 실행시 아래처럼 페이지가 뜸

Greeting

morning and afternoon
at night
  • Hello
  • good night
  • see you late


3. 다이어그램



4. 관련패턴
  1) Template Method 패턴
      builder에서는 director 가 builder를 조정하지만
       Template 에서는 상위 클래스가 하위 클래스를 조정

  2) 생성 결과물이 Composite 패턴이 되는 경우가 있습니다.

  3) Facade 의 인터페이스를 director 가 제공해줘서 규격을
      통일 시킵니다.

댓글 없음:

댓글 쓰기