<디자인패턴입문> 6. Abstract Factory 패턴
by BFine반응형
www.yes24.com/Product/Goods/2918928
가. 무엇인가
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");
}
}
다. 정리
a. 구체적인 공장을 추가하는 것은 간단!
- 여기서 간단의 의미는 어떤 클래스와 메서드를 만들지 확실하다는 뜻이다.
- A라는 공장클래스에 버그를 수정해도 Main이나 다른 공장에 영향을 주지 않는다.
b. 부품을 새로 추가하는 것은 곤란;;
- 새로운 부품을 추가하게 되면 모든 공장에 추가해야하는 문제가 발생한다.
c. 생각
- 구조가 확실히 정해져있고 파생되는 내용이 다르면서 여러가지일 경우에 사용하면 좋을 것 같다.
추상팩토리 패턴은 어떤 완성품을 만들기위한 각각의 요소들의 설계를 만들어 조립하는 패턴이다.
반응형
'개발서적 > 디자인패턴입문' 카테고리의 다른 글
<디자인패턴입문> 8. Composite 패턴 (0) | 2021.05.01 |
---|---|
<디자인패턴입문> 7. Strategy 패턴 (0) | 2021.04.30 |
<디자인패턴입문> 5. Bridge 패턴 (0) | 2021.04.25 |
<디자인패턴입문> 4. Prototype 패턴 (0) | 2021.04.24 |
<디자인패턴입문> 3. Template Method 패턴 (0) | 2021.04.22 |
블로그의 정보
57개월 BackEnd
BFine