chjs93 2021. 1. 5. 00:01

복잡한 인스턴스 조립하기

 

본 글은 'java 언어로 배우는 디자인 패턴 입문' 을 바탕으로 기재한 내용입니다.


빌딩,

구조를 가지고 있는 커다란 것을 건축하거나 구축하는 것을 build 라고 한다.

빌딩을 세울 때 우선 지반을 다지고, 골격을 세우고, 아래서 부터 위로 조금씩 만들어 단계를 밟아가며 건축을 하듯이

구조를 가진 인스턴스를 쌇아 올리는 패턴을 Builder 패턴 이라고 한다.

예제 프로그램

'문서'를 작성하는 프로그램

이름 해설
Builder 문서를 구성하기 위한 메소드를 결정하는 추상 클래스
Director 한 개의 문서를 만드는 클래스
TextBuilder 일반 텍스트(보통의 문자열)를 이용해서 문서를 만드는 클래스
HTMLBuilder HTML 파일을 이용해서 문서를 만드는 클래스
Main 동작 테스트용 클래스

Builder 클래스

'문서'를 만들 메소드들을 선언하고 있는 추상 클래스

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();
}

- 타이틀, 문자열, 개별 항목을 문서안에 구축하는 메소드이며 close()는 문서를 완성시키는 메소드이다.

 

Director 클래스

public class Director {
    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();
    }
}

- 생성자의 인수는 Builder형이지만 Builder 는 추상 클래스이므로 Builder 클래스의 인스턴스가 인수로 주어지는 경우는 없다.

Director의 생성자에게 실제로 전달되는 것은 Builder 클래스의 하위 클래스(TextBuilder 클래스나 HTMLBuilder 클래스 등) 의 인스턴스이다.

 

TextBuilder 클래스

public class TextBuilder extends Builder {

    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 void close() {
        buffer.append("======================\n");
    }

    public String getResult() {
        return buffer.toString();
    }
}

- 결과 반환은 String

 

HTMLBuilder 클래스

import java.io.FileWriter;
import java.io.PrintWriter;

public class HTMLBuilder extends Builder {
    private String filename;
    private PrintWriter writer;

    @Override
    public void makeTitle(String title) {
        filename = title + ".html";
        try {
            writer = new PrintWriter(new FileWriter(filename));
        } catch (Exception 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 void close() {
        writer.println("</body></html>");
        writer.close();
    }

    public String getResult() {
        return filename;
    }
}

 

Main

public class Main {
    public static void main(String[] args) {
        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();
            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);
        }
    }

    private static void usage() {
        System.out.println("Usage: java Main plain 일반 텍스트로 문서작성");
        System.out.println("Usage: java Main html HTML 파일로 문서작성");
    }
}