Factory Pattern - 해당되는 글 1건

이번 강좌는 많이 사용하지만 어떤것인지 잘 모르는 상태에서 사용하는 "팩토리 패턴"에 대해서 알아보도록 하겠습니다. 팩토리 패턴은 이름처럼 공장에서 무언가를 찍어내지만, 사용하는 사람은 제품만 사용할뿐 공장에서 어떻게 물건을 찍어내는지 관심이 없습니다. 그럼 자세한 내용은 아래에서 확인하겠습니다.

당신은 런타임동안 생성 되어질 정확한 클래스를 몰라도 된다. 자바스크립트의 경우, 이것은 브라우져 차이에 달라진다

만약 IE라면, 클래스의 인스턴스를 생성해야 한다. 만약 IE가 아니라면, 다른것을 생성해야 한다.
이것의 핵심은 반환된 오브젝트가 클래스의 인터스턴스와는 상관없이
같은 인터페이스(프로퍼티들과
메소스들) 가진다는 것이다.

자바스크립트는 느슨한 타입(loosely type)이고  인터페이스(interface)의 개념이 존재하지 않지만, 리턴된 오브젝트가 프로그램에 필요한 프로퍼티들 또는 메소드들이 존재한다는 것을 믿어야 한다. 가장 좋은 예는 XMLHttp 오브젝트를 생성하는 것이다. 당신은 아래와 같은 모습을 자주 보게 될 것이다.

if (typeof(XMLHttpRequest) != "undefined"){

   return new XMLHttpRequest();

} else if(typeof(window.ActiveXObject) !=  "undefined") {

  return new ActiveXObject("MSXML2.XMLHttp");

}

분영히 당신은 XMLHttp 오브젝트를 생성하기 위해 매번 코드를 반복하는 것을 원하지 않을것이다.

팩 토리 패턴(Factory Pattern)은 해당하는 오브젝트를 리턴해주는 함수(또는 오브젝트안에서의 메소드) 를 가지고 있다. 개발자들은 리턴되는 오브젝트를 알 필요가 없다. 단지 당신은 함수를 호출하기만 하면되고 해당 오브젝트가 리턴된다는 것만 알면 된다. 예를들어

function XMLHttpFactory(){

}

XMLHttpFactory.createXMLHttp = function(){

if (typeof(XMLHttpRequest) != "undefined"){

return new XMLHttpRequest();

} else {

return new ActiveXObject("MSXML2.XMLHttp");

}

}

이렇게 정의가 되어있고, 개발자들은 오브젝트를 생성하기위해 메소드를 사용할 수 있다.

var oXMLHttp = XMLHttpFactory.createXMLHttp();

만 약 다른조건이 필요하게 된다면, 사용중인 XMLHttp 오브젝트와 충돌없이 메소드를 추가할 수 있다. 많은 OOP언어들은 팩토리 패턴으로부터 리턴된 클래스들은 외부 클래스 또는 외부 패키지에서 생성하지 못하도록 Private 또는 Protected 생성자를 가진다. 자바스크립트는 non-public 생성자의 개념이 없으므로

이러한 개념을 적용하기 위해서는 다른방식으로 접근하여 사용할 필요가 있다.

MyClass라는 팩토리 메소드(MyFactory.createObject())로부터 생성된 클래스가 있다.

function MyClass(){

this.myproperty = "hello world";

}

function MyFactory {}

MyFactory.createObject = function(){

return new MyClass();

}

위의 소스로 당신은 아래와  같이 사용하는 개발자들을 막기를 바랄 것이다.

var oMyObject = new MyClass();

하지만 위의 코드를 사용하는 개발자를 막을 수는 없다. Private  또는 Protected의 생성자를 가지는
전통적인 언어들과는 달리 자바스크립트는 위의 방식에
대한 catch코드를 가지고 있지 않다.  그대신,
당신은 허용되지 않은 액션을 사용하는 개발자들에게 알려줄 에러를 제공해야 한다.

아래 코드를 보라. Myclass의 인스턴스는 MyFactory.createObject()의 메소드에 의해 생성되었다.
그럼, 런타임 당시 어떤 함수(또는 메소드)가 오브젝트를
생성하는지 알 수 있는방법이 있을까?
대답은 "YES"이다. 각 함수들은 자신을 호출할때의 진입점인 caller 프로퍼티를 가진다

function MyClass(){

if (MyClass.caller != MyFactory.createObject) {

throw new Error ("There is no public constructor for MyClass");

}

this.myproperty = "hello world";

}

위의 코드로 당신은 생성자가 caller 프로퍼티 체크에 의해 MyFactory.ceateObject() 메소드로부터
생성된다는 사실을 확인하였다.

팩토리 패턴에 대한 중요 키포인트를 기억하라

  1. 함수 또는 메소드로부터 반환되는 모든 오브젝트들은 같은 인터페이스(프로퍼티와 메소드)를 가진다
  2. 가능한 오브젝트는 직접적으로 생성하지 말고 팩토리 메소들에 의해 생성한다.
  3. 팩토리 메소드는 당신이 생성한 어디에서든지 사용되어져야 한다.

    posted by blankus
Javascript_pro  |  2007/06/26 22:00