출처 : 책 - java 언어로 배우는 디자인 패턴 입문
8. Abstract Factory - 복잡한 인스턴스 조립하기
1. 목적
- 부품 인스턴스'들'의 생성을 하위 클래스로 넘긴다.
> 즉 부품보다 부품의 조립에 집중할 수 있게된다.
- 인스턴스가 1개만 있으면 팩토리 메소드 디자인패턴으로 처리해도 된다.
> 예시) 키보드 인터페이스에 LG 키보드 or 삼성 키보드 할당
- 하지만 인스턴스가 여러개인 경우는 인스턴스들을 감싼 팩토리를 만들어
인스턴스들을 한꺼번에 생성한 후 팩토리를 할당한다.
> 예시) 키보드 - 삼성 or LG 할당 , 마우스 - 삼성 or LG 할당 (X)
컴퓨터 - 삼성 or LG 컴퓨터 할당(해당 브랜드 마우스, 키보드 생성은 컴퓨터 인스턴스 안에서 처리) (O)
- 이렇게 인스턴스들을 생성하는 Factory를 갈아 끼울 수 있도록 한다.
> Factory Method은 하나의 군에 대한 생성하는 정보(Builder 클래스)를 감추는 느낌이 있다면
Abstract Factory 는 여러 군들에 관한 생성을 감추는 느낌이다.
(출처: https://hamait.tistory.com/869 [HAMA 블로그])
2. 예제
(1) Main
> listfactory.Listfactory 를 문자열로 입력한다고 가정.
> HTML을 생성하는 프로그램이다.
import factory.*;
public class Main {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java Main class.name.of.ConcreteFactory");
System.out.println("Example 1: java Main listfactory.ListFactory");
System.out.println("Example 2: java Main tablefactory.TableFactory");
System.exit(0);
}
Factory factory = Factory.getFactory(args[0]);
Link joins = factory.createLink("중앙일보", "http://www.joins.com/");
Link chosun = factory.createLink("조선일보", "http://www.chosun.com/");
Link us_yahoo = factory.createLink("Yahoo!", "http://www.yahoo.com/");
Link kr_yahoo = factory.createLink("Yahoo!Korea", "http://www.yahoo.co.kr/");
Link excite = factory.createLink("Excite", "http://www.excite.com/");
Link google = factory.createLink("Google", "http://www.google.com/");
Tray traynews = factory.createTray("신문");
traynews.add(joins);
traynews.add(chosun);
Tray trayyahoo = factory.createTray("Yahoo!");
trayyahoo.add(us_yahoo);
trayyahoo.add(kr_yahoo);
Tray traysearch = factory.createTray("검색엔진");
traysearch.add(trayyahoo);
traysearch.add(excite);
traysearch.add(google);
Page page = factory.createPage("LinkPage", "영진닷컴");
page.add(traynews);
page.add(traysearch);
page.output();
}
}
(2) Factory - 인스턴스들(Link, Tray, Page)을 생성하는 역할
> classnamfactory = (Factory)Class.forName(classname).newInstance();
> 문자열 변수(classname)와 일치하는 클래스의 인스턴스를 생성하는 문장이다.
public abstract class Factory {
public static Factory getFactory(String classname) {
Factory factory = null;
try {
factory = (Factory)Class.forName(classname).newInstance();
} catch (ClassNotFoundException e) {
System.err.println("클래스 " + classname + " 이 발견되지 않습니다.");
} catch (Exception e) {
e.printStackTrace();
}
return factory;
}
public abstract Link createLink(String caption, String url);
public abstract Tray createTray(String caption);
public abstract Page createPage(String title, String author);
}
(3) Item - 인스턴스로 만들 클래스들 중 Link, Tray의 인터페이스
public abstract class Item {
protected String caption;
public Item(String caption) {
this.caption = caption;
}
public abstract String makeHTML();
}
(4) Link, Tray, Page, - 인스턴스로 생성할 클래스들
public abstract class Link extends Item {
protected String url;
public Link(String caption, String url) {
super(caption);
this.url = url;
}
}
public abstract class Tray extends Item {
protected ArrayList tray = new ArrayList();
public Tray(String caption) {
super(caption);
}
public void add(Item item) {
tray.add(item);
}
}
public abstract class Page {
protected String title;
protected String author;
protected ArrayList content = new ArrayList();
public Page(String title, String author) {
this.title = title;
this.author = author;
}
public void add(Item item) {
content.add(item);
}
public void output() {
try {
String filename = title + ".html";
Writer writer = new FileWriter(filename);
writer.write(this.makeHTML());
writer.close();
System.out.println(filename + " 을 작성했습니다.");
} catch (IOException e) {
e.printStackTrace();
}
}
public abstract String makeHTML();
}
--------------------------------------------------------------------------------
위 Factory와 Link, Tray, Page는 추상클래스 이므로 Main에 입력한 listfactory.Listfactory 구현 클래스가 할당된다.
(1) ListFactory
package listfactory;
public class ListFactory extends Factory {
public Link createLink(String caption, String url) {
return new ListLink(caption, url);
}
public Tray createTray(String caption) {
return new ListTray(caption);
}
public Page createPage(String title, String author) {
return new ListPage(title, author);
}
}
(2) ListLink
public class ListLink extends Link {
public ListLink(String caption, String url) {
super(caption, url);
}
public String makeHTML() {
return " <li><a href=\"" + url + "\">" + caption + "</a></li>\n";
}
}
(3) ListPage
public class ListPage extends Page {
public ListPage(String title, String author) {
super(title, author);
}
public String makeHTML() {
StringBuffer buffer = new StringBuffer();
buffer.append("<html><head><title>" + title + "</title></head>\n");
buffer.append("<body>\n");
buffer.append("<h1>" + title + "</h1>\n");
buffer.append("<ul>\n");
Iterator it = content.iterator();
while (it.hasNext()) {
Item item = (Item)it.next();
buffer.append(item.makeHTML());
}
buffer.append("</ul>\n");
buffer.append("<hr><address>" + author + "</address>");
buffer.append("</body></html>\n");
return buffer.toString();
}
}
(4) ListTray
public class ListTray extends Tray {
public ListTray(String caption) {
super(caption);
}
public String makeHTML() {
StringBuffer buffer = new StringBuffer();
buffer.append("<li>\n");
buffer.append(caption + "\n");
buffer.append("<ul>\n");
Iterator it = tray.iterator();
while (it.hasNext()) {
Item item = (Item)it.next();
buffer.append(item.makeHTML());
}
buffer.append("</ul>\n");
buffer.append("</li>\n");
return buffer.toString();
}
}
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 10. Strategy (0) | 2021.01.10 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 분리해서 생각하기 9. Bridge (0) | 2021.01.10 |
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 7. Builder (0) | 2021.01.08 |
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 6. Prototype (0) | 2021.01.08 |
[Java 언어로 배우는 디자인 패턴 입문] 인스턴스 만들기 5. Singleton (0) | 2021.01.07 |
댓글