You will be fine

<디자인패턴입문> 6. Abstract Factory 패턴

by BFine
반응형

www.yes24.com/Product/Goods/2918928

 

Java 언어로 배우는 디자인 패턴 입문

이 책은 디자인 패턴의 입문서입니다. GoF가 정리한 23개의 디자인 패턴을 하나씩 다루면서 객체 지향을 잘 모르는 초보자도 이해하기 쉽도록 정리하고 있습니다. 단순한 이론이나 논리을 제시하

www.yes24.com

 

가. 무엇인가

 a. 추상적인 공장에서 추상적인 부품을 조립!

  -  추상화된 부품을 사용해 추상적인 제품을 완성한다.

       => 여기서 추상화되었다는 것은 인터페이스를 의미한다. 즉 명세만 가지고 만드는 것이다.

  -  실제 구현은 하위 클래스 단계에서 이루어진다.

 

나. 예제

 a. Abstract Factory (추상적인 공장) 역할

  -  이 예제는 html을 추상팩토리 패턴을 이용하여 생성한다. (Page는 html 틀을 담당한다)   

  -  Factory에서 구체적인 Factory를 리플랙션을 통해 생성한다. 

      => new로 생성해도 상관없다. 

  -  추상적인 부품들 하나하나 생성할 수 있는 걸 알 수 있다. 

public abstract class Factory {
    public static Factory crateFactory(String className){
        Factory factory = null;
        try {
            factory = (Factory) Class.forName(className).getDeclaredConstructor()
            		  .newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factory;
    }
    public abstract Header crateHeader(String title);
    public abstract Body crateBody();
    public abstract Page cratePage(Header header,Body body);
}

 

 b. Abstract Product (추상적인 제품) 역할

public interface Body {
    void addContent(String content);
    String makeHtml();
}

public interface Header {
    String makeHtml();
}

public abstract class Page {
    protected Header header;
    protected Body body;

    public Page(Header header,Body body) {
        this.header = header;
        this.body = body;
    }

    public void output(String name) {
        try {
            String filename = name+".html";
            Writer writer = new FileWriter(filename);
            writer.write(makeHTML());
            writer.close();
            System.out.println(filename + " 을 작성했습니다.");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public abstract String makeHTML();
}

 

 c. Concreate Factory (구체적인 공장) 역할

  -   내용을 보면 서로 다른 공장에서 각자의 구현체를 만드는 것을 알 수 있다.

public class ListFactory extends Factory {

    @Override
    public Header crateHeader(String title) {
        return new ListHeader(title);
    }

    @Override
    public Body crateBody() {
        return new ListBody();
    }

    @Override
    public Page cratePage(Header header,Body body) {
        return new ListPage(header,body);
    }
}

public class TableFactory extends Factory {
    @Override
    public Header crateHeader(String title) {
        return new TableHeader();
    }

    @Override
    public Body crateBody() {
        return new TableBody();
    }

    @Override
    public Page cratePage(Header header, Body body) {
        return new TablePage(header, body);
    }
}

 

 d. Concreate Product (구체적인 제품) 역할

  -   리스트 공장에서는 body를 li 태그를 만들고 테이블 공장에서는 td 태그로 html을 구성한다.   

public class ListBody implements Body {
    List<String> contentList = new ArrayList<>();

    @Override
    public void addContent(String content) {
        contentList.add(content);
    }

    @Override
    public String makeHtml() {

        StringBuilder builder = new StringBuilder();
        for (String content: contentList) {
            builder.append("<li>")
                    .append(content)
                    .append("</li>\n");
        }

        return builder.toString();
    }
}

public class ListHeader implements Header {
    String title;

    public ListHeader(String title) {
        this.title = title;
    }

    @Override
    public String makeHtml() {
        StringBuilder builder = new StringBuilder();
            builder.append("<head>\n")
                    .append("<meta charset=\"UTF-8\">")
                    .append("<h1>"+title+"</h1>")
                    .append("</head>\n");
        return builder.toString();
    }
}

public class ListPage extends Page {

    public ListPage(Header header, Body body) {
        super(header,body);
    }

    @Override
    public String makeHTML() {
        StringBuilder builder = new StringBuilder();
        builder.append("<html>\n");
        builder.append(header.makeHtml());
        builder.append("<body>\n");
        builder.append(body.makeHtml());
        builder.append("</body>\n");
        builder.append("</html>");
        return builder.toString();
    }
}

public class TableBody implements Body {
    List<String> contentList = new ArrayList<>();

    @Override
    public void addContent(String content) {
        contentList.add(content);
    }

    @Override
    public String makeHtml() {

        StringBuilder builder = new StringBuilder();
        builder.append("<table border=\"1\">\n");
        for (String content: contentList) {

            builder.append("<td>")
                    .append(content)
                    .append("</td>\n");
        }
        builder.append("</table>");

        return builder.toString();
    }
}

public class TableHeader implements Header {
    String title;

    public TableHeader(String title) {
        this.title = title;
    }

    @Override
    public String makeHtml() {
        StringBuilder builder = new StringBuilder();
        builder.append("<head>\n")
                .append("<meta charset=\"UTF-8\">")
                .append("<h1><u>"+title+"</u></h1>")
                .append("</head>\n");
        return builder.toString();
    }
}

public class TablePage extends Page {
    public TablePage(Header header, Body body) {
        super(header, body);
    }

    @Override
    public String makeHTML() {
        StringBuilder builder = new StringBuilder();
        builder.append("<html>\n");
        builder.append(header.makeHtml());
        builder.append("<body>\n");
        builder.append(body.makeHtml());
        builder.append("</body>\n");
        builder.append("</html>");
        return builder.toString();
    }
}


 

 e. Main (Client)

  -   단순히 구현팩토리의 종류와 인터페이스만 알고서 제품을 받는 클라이언트 역할을 담당한다.

public class Main {

    public static void main(String[] args) {

        //Factory factory = Factory.crateFactory(ListFactory.class.getName());
        Factory factory = Factory.crateFactory(TableFactory.class.getName());

        Body body = factory.crateBody();
        Header header = factory.crateHeader("제목");
        body.addContent("가");
        body.addContent("나");
        body.addContent("다");
        body.addContent("라");

        Page page = factory.cratePage(header, body);
        page.output("example");


    }
}

ListFactory, TableFactory

 

다. 정리

 a. 구체적인 공장을 추가하는 것은 간단!

  -  여기서 간단의 의미는 어떤 클래스와 메서드를 만들지 확실하다는 뜻이다. 

  -  A라는 공장클래스에 버그를 수정해도 Main이나 다른 공장에 영향을 주지 않는다.

 

 b. 부품을 새로 추가하는 것은 곤란;;

  -  새로운 부품을 추가하게 되면 모든 공장에 추가해야하는 문제가 발생한다.

 

 c. 생각

  -  구조가 확실히 정해져있고 파생되는 내용이 다르면서 여러가지일 경우에 사용하면 좋을 것 같다.  

 

추상팩토리 패턴은 어떤 완성품을 만들기위한 각각의 요소들의 설계를 만들어 조립하는 패턴이다.
반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기