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가 모르기 때문에 몰래 재료를 바꾸는 것이 가능하다는 소리입니다.(몰래 값싼 재료 써도 됨!)
'프로그래밍 > 자바 디자인패턴' 카테고리의 다른 글
디자인 패턴 위임에 의한 Adapter 패턴(인스턴스를 이용한) (0) | 2012.08.03 |
---|---|
디자인 패턴 Adapter패턴 상속을 사용한 Adapter패턴 (0) | 2012.08.03 |
디자인패턴 Chain of Responsibility 패턴 (0) | 2012.08.02 |
디자인 패턴 Visitor 패턴 (0) | 2012.08.01 |
디자인 패턴 Decorator 패턴 (0) | 2012.08.01 |
디자인 패턴 Composite 패턴 (0) | 2012.08.01 |
디자인 패턴 Strategy 패턴 (0) | 2012.08.01 |
디자인 패턴 Bridge 패턴 (0) | 2012.08.01 |