The Factory Pattern

객체 지향 프로그램에서 계속해서 볼 수 있는 패턴 중의 하나는 Factory 패턴 또는 클래스이다. Factory 패턴은 제공된 데이터에 의존하는 여러 가능한 클래스 중의 하나를 반환하는 것이다. 일반적으로 반환되는 모든 클래스는 공통적인 부모 클래스와 공통적인 메소들을 가지지만, 그것들은  각각은 다른 일을 하고, 다른 종류의 데이터를 위해 최적화 되어진다.

How a Factory Works

아래의 Factory 다이어 그램은 Factory 패턴의 이해를 돕기 위한 것이다.

##########0*

그림에서 x는 상위 클래스이고 xy와 xz는 x로 부터 파생되었다. Factory는 입력된 인자에 의존하여 하위 클래스를 반환을 결정하는 클래스이다. 오른쪽에서 어떤 abc라는 값이 주어질 때의 getClass 메소드를 정의하였고, 이 메소드는 클래스 x의 인스턴스를 반환한다. 모두 같은 메소드를 가지고 있기 때문에 반환되는 getClass가 어떤 값을 반환하는가는 문제가 되지 않지만, 구현은 다르다. 어떻게 반환할 것인가를 결정하는 것은 전반적으로 Factroy에 의해서 이다. 

Sample Code

    Factory 클래스를 사용할 수 있는 간단한 경우를 고려해 보자.
우리가 어떤 가입 양식을 가지고 있고, 가입자가 그의 이름을 "이름 성" 또는 "성, 이름" 모두 가능하게 하고자 한다고 하자. 우리는 이름과 성 사이의 컴마(,)가 있는지 없는지를 고려하여 항상 이름의 순서를  결정할 수 있도록 좀더 가정을 단순화 시킬 것이다. 
class Namer {

	// a simple class to take a string apart into two names
	
	protected String last; 	//store last name here
	protected String first;	//store first name here
	
	public String getFirst() {
		return first;	//return first name
	}
	public String getLast() {
		return last;	//return last name
	}	
}

상위 클래스에는 두 개의 메소드를 제외하고는 실제적으로 아무일 도 하지 않는다. 우리는 first last 에 성과 이름을 분리하여 저장할 것이다. 

The Two Derived Classes

우리는 간단하게 생성자를 이용하여 이름을 두개의 부분으로 나누는 클래스를 파생시킬 수 있다. FirstFirst 클래스에서는 공백문자 이전의 모든 것들은 이름(last name)이라 가정한다.
class FirstFirst extends Namer { 		//split first last
	public FirstFirst(String s) {
		int i = s.lastIndexOf(" "); 	//find sep space
		if( i>0) {
			//left is first name 
			first = s.substring(0,i).trim();
			//right is last name
			last = s.substring(i+1).trim();
		}
		else {
			first = ""; 	// put all in last name
			last = s;	// if no space
		}
	}
}
그리고, LastFirst 클래스에서는 컴마(,)를 구분자로 하여 컴마 이전의 것은 이름(last)에 이후는 성(fist)에 저장할 것이다. 만약 컴마가 존재하지 않는다면 이름에 저장할 것이다.
class LastFirst extends Namer {	//split last, first
	public LastFirst(String s) {
		int i = s.indexOf(",");	//find comma
		if (i>0) {
			//left is last name 
			last = s.substring(0,i).trim();
			//right is first name
			first = s.substring(i+1).trim();
		}
		else {
			last = s; 	//put all in last name
			first = "";	//if no comma
		}
	}
}

Building the Factory

Factory 클래스는 아주 간단하다. 우리는 컴마의 존재 유무를 검사한 후 상속 받은 두 클래스중 하나의 인스턴스를 반환할 것 이다.
class NameFactory {
//returns all instance of LastFirst or FirstFirst
//depending on whether a comma is found

	public Namer getNamer(String entry) {
		int i = entry.indexOf(","); //comma determines name order
		if (i>0)
			return new LastFirst(entry); 	//return one class
		else
			return new FirstFirst(entry);	//or the other
	}
}
Using the Factory
어떻게 Factory를 사용하는지 알아 보자.
간단하게 성과 이름을 입력할 수 있는 입력창과 이름과 성을 분리하도록 명령을 내리는 버튼, 그에 따라 각각 분리하여 나타낼 수 있는 두 개의 결과창을 사용자 인터페이스로 구현해 보자. 아래의 그림은 구현은 이러한 일련의 작업을 구현해 놓은 애플릿이다.

            ##########1*

이름을 입력하고 Compute 버튼을 누르면 이름과 성이 분리되어 각각의 결과를 얻을 수 있을 수 있을 것이다.
이 프로그램을 작성하기 위해 우리는 생성자에 Factory 클래스를 생성하여야 한다.

 NameFactory nfactory = new NameFactory();

그리고 나서 버튼 이벤트가 발생하였을 때 이름과 성을 분리할 수 있는 getNamer메소드를 호출 할 compteName이라는 메소드를 구현해야 한다. 

	private void computeName () {
		//send the text to the factory and get a class back
		namer = nfactory.getNamer(entryField.getText());
		
		//compute the first and last names
		//using the returned class
		txFirstName.setText(namer.getFirst());
		txLastName.setText(namer.getLast());
	}

When to Use a Factory Pattern

다음과 같은 상황에서 Factory 패턴을 고려할 수 있다.
  • 객체들에 대한 클래스의 종류를 예상 할 수 없을 때
  • 어떤 객체들이 Factory Pattern을 생성하는지를 특정 짓기 위하여 클래스의 하위 클래스를 사용할 때
  • 생성된 클래스로터 얻어진 정보 제한하고자 할 때
Factory 패턴에 대한 여러가지 변형이 있다.
  1. 기본 클래스는 추상(abstract)이고 그 패턴은 완전하게 작동하는 클래스를 반환하여야 한다
  2. 기본 클래스는 디폴트 메소드들을 포함하고 오직 하위 클래스들이 .....
##########2*

'Development > 패턴자료' 카테고리의 다른 글

[펌] The History of Design Patterns  (0) 2011.08.13
[펌] The Flyweight Pattern  (0) 2011.08.13
[펌] The Facade Pattern  (0) 2011.08.13
[펌] The Decorator Pattern  (0) 2011.08.13
[펌] The Composite Pattern  (0) 2011.08.13
안정적인 DNS서비스 DNSEver DNS server, DNS service
Posted by 키르히아이스
,