송민준의 개발노트

Builder 패턴 본문

JAVA/디자인패턴

Builder 패턴

송민준 2021. 8. 30. 22:27

예전에 Builder 패턴을 처음 들었을 때 lombok에 Builder를 사용하는 건줄 알았다.(무지했다... 지금도 무지하지만...)

Builder 패턴은 말 그대로 우선 전체를 구성하고 있는 각 부분을 만들고 단계를 밟아 만들어 나가는 것을 말한다.

 

텍스트 및 HTML 문서를 만드는 Builder를 예로 들겠다.

 

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

 

2. Director 클래스

Builder 클래스에 선언되어 있는 메소드를 사용해서 문서를 만든다. Director 클래스는 Builder 클래스의 어떤 하위 클래스가 오는지 모른다. 이는 큰 장점인데 하위 클래스가 무엇인지 모르기 때문에 교체가 가능한 것이다.

그리고 목적 달성을 위한 필요 충분한 메소드를 구현했는지 확인해야 한다. 가까운 미래에 예상되는 변화에 적응할 수 있도록 설계하는 것도 중요하다.

/**
 * 한 개의 문서를 만드는 클래스
 * Builder 클래스로 선언되어 있는 메소드를 사용해서 문서를 만듬.
 */
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();
    }
}

 

3. TextBuilder 클래스

일반 문서를 작성하는 Builder 하위 클래스의 한 종류

/**
 * 일반 텍스트를 이용해서 문서를 만드는 클래스
 */
public class TextBuilder extends Builder {
    private StringBuffer buffer = new StringBuffer();
    
    @Override
    public void makeTitle(String title) {
        buffer.append("==============================\n");
        buffer.append("┌").append(title).append("┘\n");
        buffer.append("\n");
    }
    
    @Override
    public void makeString(String str) {
        buffer.append('■').append(str).append("\n");
        buffer.append("\n");
    }
    
    @Override
    public void makeItems(String[] items) {
        for(int i = 0; i < items.length; i++) {
            buffer.append(" ⊙").append(items[i]).append("\n");
        }
        buffer.append("\n");
    }
    
    @Override
    public void close() {
        buffer.append("===================================\n");
    }
    public String getResult() {
        return buffer.toString();
    }
}

 

4. HTMLBuilder 클래스

/**
 * HTML 파일을 이용해서 문서를 만드는 클래스
 */
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(IOException ioe) {
            ioe.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;
    }
}

 

5. 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);
        }
    }
    public static void usage() {
        System.out.println("Usage : java Main plain 일반 텍스트로 문서작성");
        System.out.println("Usage : java Main html 파일로 문서작성");
    }
}

'JAVA > 디자인패턴' 카테고리의 다른 글

Abstract Factory 패턴  (0) 2021.10.31
Prototype 패턴  (0) 2021.08.29