본문 바로가기

자바

[자바] Abstract Factory 패턴

추상적인 공장에서 추상적인 부품을 조합해 추상적인 제품을 만든다라..

바로 예제부터 살펴보자.

예제는 계층구조를 가진 Link 페이지를 HTML 파일로 만들기 이다.

 

추상 부품

package abstractfactory.factory;

/**
 * Link와 Tray의 상위 클래스
 * @author dev-jones
 *
 */
public abstract class Item {
	
	protected String caption;
	
	public Item(String caption) {
		this.caption = caption;
	}
	
	public abstract String makeHTML();
}
package abstractfactory.factory;

/**
 * HTML의 하이퍼링크를 추상적으로 표현한 클래스
 * @author dev-jones
 *
 */
public abstract class Link extends Item {

	protected String url;
	
	public Link(String caption, String url) {
		super(caption);
		this.url = url;
	}
}
package abstractfactory.factory;

import java.util.ArrayList;

/**
 * 복수의 Link나 Tray를 모아서 합친 것을 표시하는 클래스.
 * @author dev-jones
 *
 */
public abstract class Tray extends Item {

	protected ArrayList<Item> tray = new ArrayList<Item>();
	
	public Tray(String caption) {
		super(caption);
	}
	
	public void add(Item item) {
		tray.add(item);
	}
}

 

추상제품

package abstractfactory.factory;

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

/**
 * HTML 페이지 전체를 추상적으로 표현하는 클래스
 * @author dev-jones
 *
 */
public abstract class Page {

	protected String title;
	protected String author;
	protected ArrayList<Item> content = new ArrayList<Item>();
	
	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();
}

 

추상공장

package abstractfactory.factory;

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);
}

 


 

구체부품

package abstractfactory.listfactory;

import abstractfactory.factory.Link;

public class ListLink extends Link {

	public ListLink(String caption, String url) {
		super(caption, url);
	}

	@Override
	public String makeHTML() {
		return "<li><a href=\"" + url + "\">" + caption + "</a></li>\n";
	}

}
package abstractfactory.listfactory;

import java.util.Iterator;

import abstractfactory.factory.Item;
import abstractfactory.factory.Tray;

public class ListTray extends Tray {

	public ListTray(String caption) {
		super(caption);
	}

	@Override
	public String makeHTML() {
		
		StringBuffer buffer = new StringBuffer();
		
		buffer.append("<li>\n");
		buffer.append(caption + "\n");
		buffer.append("<ul>\n");
		
		Iterator<Item> trayItr = tray.iterator();
		while(trayItr.hasNext()) {
			Item item = trayItr.next();
			buffer.append(item.makeHTML());
		}
		
		buffer.append("</ul>\n");
		buffer.append("</li>\n");
		
		return buffer.toString();
	}

}

 

구체적인 제품

package abstractfactory.listfactory;

import java.util.Iterator;

import abstractfactory.factory.Item;
import abstractfactory.factory.Page;

public class ListPage extends Page {

	public ListPage(String title, String author) {
		super(title, author);
	}

	@Override
	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<Item> contentItr = content.iterator();
		while(contentItr.hasNext()) {
			Item item = contentItr.next();
			buffer.append(item.makeHTML());
		}
		
		buffer.append("</ul>\n");
		buffer.append("<hr><address>" + author + "</address>");
		buffer.append("</body></html>\n");
		
		return buffer.toString();
	}

}

 

 구체공장

package abstractfactory.listfactory;

import abstractfactory.factory.Factory;
import abstractfactory.factory.Link;
import abstractfactory.factory.Page;
import abstractfactory.factory.Tray;

public class ListFactory extends Factory {

	@Override
	public Link createLink(String caption, String url) {
		return new ListLink(caption, url);
	}

	@Override
	public Tray createTray(String caption) {
		return new ListTray(caption);
	}

	@Override
	public Page createPage(String title, String author) {
		return new ListPage(title, author);
	}

}

package abstractfactory;

import abstractfactory.factory.Factory;
import abstractfactory.factory.Link;
import abstractfactory.factory.Page;
import abstractfactory.factory.Tray;

// listfactory 를 전혀 import하지 않았다는 점.
public class Main {
	public static void main(String[] args) {

		Factory factory = Factory.getFactory("abstractfactory.listfactory.ListFactory");
		
		Link joins = factory.createLink("중앙일보", "https://joins.com/");
		Link chosun = factory.createLink("조선일보", "https://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", "www.excite.com");
		Link google = factory.createLink("Google", "https://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();
	}
}

 

결과:

LinkPage.html 을(를) 작성했습니다.

 

<html><head><title>LinkPage</title></head>
<body>
<h1>LinkPage</h1>
<ul>
<li>
신문
<ul>
<li><a href="https://joins.com/">중앙일보</a></li>
<li><a href="https://www.chosun.com/">조선일보</a></li>
</ul>
</li>
<li>
검색엔진
<ul>
<li>
Yahoo!
<ul>
<li><a href="http://www.yahoo.com">Yahoo!</a></li>
<li><a href="http://www.yahoo.co.kr">Yahoo!Korea</a></li>
</ul>
</li>
<li><a href="www.excite.com">Excite</a></li>
<li><a href="https://google.com">Google</a></li>
</ul>
</li>
</ul>
<hr><address>네이버닷컴</address></body></html>

'자바' 카테고리의 다른 글

InputStream과 InputStreamReader  (0) 2021.06.13
[자바] Proxy 패턴  (0) 2021.06.12
[자바] bridge 패턴  (0) 2021.06.07
[자바] composite 패턴  (0) 2021.06.06
[자바] Observer 패턴  (0) 2021.06.03