디자인패턴

[Java] Builder 패턴

ZzangHo 2022. 4. 25. 23:40
728x90

디자인 패턴 공부용으로 블로그에 기록을 해본다.

공부에 참고한 자료로는 "Java 언어로 배우는 디자인 패턴 입문" 을 참고 하였다.

정의

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

 

클래스 설명

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

 

Builder 클래스

여기서 builder 클래스는 '문서'를 만들 메소드들을 선언하고 있는 추상 클래스이다.
package 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();
}

 

Director 클래스

Director 클래스는 Builder 하위 클래스를 인수로 받는다.(Builder 클래스는 추상클래스이기 때문에 인스턴스를 만들 수 없다.)
주어진 하위 클래스 종류에 따라 구체적인 문서의 형식이 정해진다.
construct 메소드는 문서를 만드는 메소드 이며, Builder에서 선언되어 있는 메소드만 사용한다.
package Builder;

public class Dircetor {
    private Builder builder;

    public Dircetor(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 클래스

Builder 클래스 메소드들의 인자를 Text형태로 만드는 클래스
package Builder;

public class TextBuilder extends Builder{
    private StringBuffer sb = new StringBuffer();
    @Override
    public void makeTitle(String title) {
        sb.append("==============================\n");
        sb.append("[" + title + "]\n");
        sb.append("\n");
    }

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

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

    @Override
    public void close() {
        sb.append("==============================\n");
    }

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

 

 

HtmlBuilder 클래스

Builder 클래스 메소드들의 인자를 Html 파일 형태로 만드는 클래스
package Builder;

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

public class HtmlBuilder extends Builder {
    private String filename;
    private PrintWriter printWriter;
    @Override
    public void makeTitle(String title) {
        filename = title + ".html";
        try {
            printWriter = new PrintWriter(new FileWriter(filename));

        } catch (IOException e) {
            e.printStackTrace();
        }
        printWriter.println("<html><head><title>" + title + "</title></head><body>");
        printWriter.println("<h1>" + title + "</h1>");
    }

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

    @Override
    public void makeItems(String[] items) {
        printWriter.println("<ul>");
        for (String item : items) {
            printWriter.println("<li>" + item + "</li>");
        }
        printWriter.println("</ul>");
    }

    @Override
    public void close() {
        printWriter.println("</body></html>");
        printWriter.close();
    }

    public String getResult() {
        return filename;
    }
}

 

Main 클래스

파라미터를 전달받아(plain or html) plain 일때는 텍스트 형태의 문서를 만들고 html 일때는 html 파일 형태의 문서를 만든다.
아래 구현 로직을 보면 Director 클래스는 TextBuilder 또는 HtmlBuilder 클래스를 생성자의 인수로 받고 있으며 construct()메소드를 호출한다.
기서 주목해야 할 것은 Director 클래스는 자신이 실제로 이용하고 있는 클래스가 무엇인지 모른다. 이것은 아주 잘 된 일이다.
왜냐하면 모르기 때문에 TextBuilder를 HtmlBuilder로 교체할 수 있기 때문이다. 
교체가 가능하다는 말은 부품으로서 가치가 높다는 말이 될 수 있다.
package Builder;

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();
            Dircetor dircetor = new Dircetor(textBuilder);
            dircetor.construct();
            String result = textBuilder.getResult();
            System.out.println(result);
        } else if (args[0].equals("html")) {
            HtmlBuilder htmlBuilder = new HtmlBuilder();
            Dircetor dircetor = new Dircetor(htmlBuilder);
            dircetor.construct();
            String result = htmlBuilder.getResult();
            System.out.println("filename : " + result);
        } else {
            usage();
            System.exit(0);
        }
    }

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

 

실행결과

/Library/Java/JavaVirtualMachines/adoptopenjdk-16.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=56351:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/zzangho/workspace/DesignPattern/out/production/DesignPattern Builder.Main plain
==============================
[Greeting]

ㅁ아침과 낮에ㅁ

 .좋은 아침입니다.
 .안녕하세요.

ㅁ밤에ㅁ

 .안녕하세요.
 .안녕히 주무세요.
 .안녕히 계세요.

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


Process finished with exit code 0

 

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

[Java] Singleton 패턴  (0) 2022.04.12
[Java] Prototype 패턴  (0) 2022.04.12
[Java] Factory 패턴  (0) 2022.04.05
[Java] Template Method 패턴  (0) 2022.04.03
[Java] Adapter 패턴  (0) 2022.04.03