본문으로 바로가기
728x90
반응형
728x170

안녕하세요. 오늘은 Builder 패턴에 대해 알아보려고 합니다.

흔히 Build라는 단어는 구조를 가지고 건물 등을 지을 때 사용할 때 쓰는 단어입니다.

 

보통 건물을 세울 때 밑에 지반을 다지고, 골격을 세우고, 아래에서 위로 조금씩 만드는 형식이죠. 

그리고 그 건물이 어려울 수록 한 번에 세우는 것 또한 쉽지 않죠. 보통은 전체를 구성하고 있는 부분들을 단계를 나누어 짓게 되는데요.

 

이런 형식의 구조를 가진 인스턴스를 쌓아 올리는 디자인 패턴이 Builder 패턴이라고 합니다.


이제 예제 프로그램을 만들어 볼 건데요. Builder 패턴을 사용하여 문서를 작성하는 프로그램을 만들어 보도록 하겠습니다.

여기에서는 다음과 같은 구조를 가지고 있는데요.

  • 타이틀을 한 개 포함한다.
  • 문자열을 몇 개 포함한다.
  • 개별 항목을 몇 개 포함한다.

Builder 클래스에서는 문서를 구성하기 위한 메소드를 결정하는데요. 그리고 Director클래스가 그 메소드를 사용하여 구체적인 하나의 문서를 만듭니다.

 

 

Builder 클래스는 추상적인 클래스인데 실제 처리는 기술하지 않고, 추상 메소드만 선언 해줍니다.

예제 프로그램에서 Bulider 클래스의 하위 클래스로 다음과 같은 클래스를 정의 하는데요.

보통의 문자열을 사용해서 문서를 만들어주는 TextBulider 클래스과 HTML을 사용해서 문서를 만드는 HTMLBuilder 클래스를 정의해줘요.

 

그래서 Director가 TextBuilder를 사용하면 일반 텍스트의 문서가 되게 되고, HTMLBuilder를 사용하면 HTML의 문서가 되는 것이죠.

 

이제 만들어보죠!


Builder 클래스는 문서를 만들 때의 메소드를 선언하고 있는 추상 클래스인데요.

package bami;

public abstract class Builder {
	public abstract void MakeTitle(String title);
	public abstract void MakeString(String str);
	public abstract void MakeItem(String[] items);
	public abstract void Close();
}

MakeTitle, MakeString, MakeItems는 변수만 봐도 추측할 수 있듯이 타이틀, 문자열 개별 아이템을 문서안에 구축해주는 메소드이고, Close 메소드는 문서를 완성시켜주는 메소드라 생각하시면 됩니다.

 

그 다음 Director 클래스를 작성해볼 것인데요.

package bami;

public class Director {
	private Builder builder;
	public Director(Builder builder) {
		this.builder = builder;
	}
	
	public void Construct() {
		builder.MakeTitle("Example Title");
		builder.MakeString("Example String");
		builder.MakeItem(new String[] {
				"이것은 예제 아이템입니다.",
				"바미 블로그에 오신 분들 환영합니다."
		});
		builder.MakeString("Example String2");
		builder.MakeItem(new String[] {
				"이것은 두번째 아이템입니다.",
				"헬로 바미."
		});
		 builder.Close();
	}
}

Builder 클래스로 선언되어 있는 메소드를 사용해서 문서를 만들어줍니다.

Director 클래스의 생성자의 인수는 Builder형이에요!

 

참고로 Builder 클래스는 추상 클래스이므로 인스턴스를 만들 수 없기 때문에 Builder 클래스의 인스턴스가 주어지는 경우는 없어요.

Director의 생성자에게 실제로 전달되는 것은 Builder 클래스의 하위 클래스인 TextBuilder 클래스나 HTMLBuilder 클래스의 인스턴스 입니다. 주어진 Builder 클래스의 하위 클래스 종류에 따라 이 클래스가 만들 문서의 형식이 정해지게 돼요.

 

또 여기서 Consturct 메소드는 문서를 만들 때 필요한 메소드이고, Builder에서 선언되어 있는 메소드를 사용해요. 이 메소드를 호출하면 문서가 만들어지게 돼요.

 

그 다음은 TextBuilder 클래스를 만들어 봅시다!

package bami;

public class TextBuilder extends Builder {
	private StringBuffer buffer = new StringBuffer();
	public void MakeTitle(String string) {
		buffer.append("------------------------------------");
		buffer.append(string + "\n");
		buffer.append("\n");
	}
	
	public void MakeString(String string) {
		buffer.append("○" + "string" + "\n");
		buffer.append("\n");
	}
	
	public void MakeItems(String[] items) {
		for (int i = 0; i < items.length; i++) {
			buffer.append("▶" + items[i] + "\n"); 
		}
		buffer.append("\n");
	}
	
	public void Close() {
		buffer.append("------------------------------------");
	}
	
	public String GetResult() {
		return buffer.toString();
	}
}

위에 말씀드렸듯이 Builder 클래스의 하위 클래스 입니다.

 

이제 HTMLBulider 클래스를 작성해봅시다!

package bami;

import java.io.*;

public class HTMLBuilder extends Builder {
	private String Filename;
	private PrintWriter Writer;
	public void MakeTitle(String string) {
		Filename = string + ".html";
		try {
			Writer = new PrintWriter(new FileWriter(Filename));
		} catch(IOException e) {
			e.printStackTrace();
		}
		Writer.println("<html><head><title>" + string + "</title></head><body>");
		Writer.println("<h1>" + string + "</h1>");	
	}
	
	public void MakeString(String string) {
		Writer.println("<p>" + string + "</p>");
	}
	
	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>");
	}
	
	public void Close() {
		Writer.println("</body></html>");
	}
	
	public String GetResult() {
		return Filename;
	}
}

 

이제 Main 클래스를 작성해봅시다.

package bami;

public class Main {
	public static void main(String[] args) {
		if (args.length != 1) {
			usage();
			System.exit(0);
		}
		if (args[0].equals("string")) {
			TextBuilder textbuilder = new TextBuilder();
			Director director = new Director(textbuilder);
			director.Construct();
			String result = textbuilder.GetResult();
			System.out.println(result);
		} else if (args[0].equals("HTML")) {
			HTMLBuilder htmlbuilder = new HTMLBuilder();
			Director director = new Director(htmlbuilder);
			director.Construct();
			String Filename = htmlbuilder.GetResult();
			System.out.println(Filename + "이 생성 되었습니다.");
		} else {
			usage();
			System.exit(0);
		}
	}
	
	public static void usage() {
		System.out.println("Usage : java Main String 일반 텍스트로 문서 작성.");
		System.out.println("Usage : java Main HTML HTML파일로 문서 작성.");
	}
}
728x90
반응형
그리드형

댓글을 달아 주세요