Javascript_pro - 해당되는 글 3건

유틸리티로서 순수하게 사용되어질 오브젝트를 가지고 있다고 상상해보라. 이 오브젝트에는 어떠한
비지니스 로직도, 변경해야할 데이터도 포함되어 있지 않다.
단지 살아있는동안 프로그램의 다른 부분에서 필요로하는 기능들을 제공하면 된다. 당신이 이 오브젝트의 인스턴스를 필요할때마다 매번 새로 생성할 필요가 있을까?
정답은 "NO"이다. 싱글톤 패턴은 한 클래스로부터 생성된 인스턴스의 갯수를 컨트롤한다. 일반적으로 getInstance() 메소스로 정의한다. 개발자들이 언제든지 오브젝트의 인스턴스가 필요할때 이 메소드는 호출된다. 클래스에는 static property가 있다. getInstance()라고 불리는 이것은 인스턴스가 이미 존재
하는지를 먼저 체크한다. 만약 인스턴스가 존재한다면 이미 생성된 인스턴스를 반환하고, 그렇지 않을경우 새로운 인스턴스를 생성하고 static property에 저장한후, 새로 생성된 인스턴스를 반환한다.
자바스크립트에서는 아래와 같다.

function MyClass() {

this.myproperty = "hello world";

}
MyClass._instance_ = null; //define the static property

MyClass.getInstance = function(){

if (this._instance_ == null){

this._instance_ = new MyClass();

}

return this._instance_;

}

간단하게 클래스를 정의한후,  static property인 _instance_ 를 정의한후, null로 할당한다. getInstance() 메소드(또한 static이다)는 static property를 체크하여 null인지 아닌지를 판단, null이라면 새로운
인스턴스를 생성하고 _instance_에 할당한다. 그리고나서 저장된 인스턴스를 함수의 반환인자로 넘긴다.
개발자들은 아래처럼 사용할 수 있다.

var oMyObject = MyClass.getInstance();

당신은 아래처럼 사용하는 개발자들을 추측할 수 있을 것이다.

var oMyObject = new MyClass();

당신은 팩토리 패턴을 사용하여 아래 처럼 수정할 수 있다.

function MyClass() {

if (Myclass.caller != MyClass.getInstance) {

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

}

this.myproperty = "hello world";

}

싱글톤 패턴에 대한 중요 키포인트를 기억하라

1. 클래스의 인스턴스는 단 하나만 생성한다
2. 팩토리 패턴과는 달리, 싱글톤 패턴은 항상 확실한 클래스의 오브젝트만 생성한다.
3. 싱글톤 패턴은 당신이 생성한 어디에서든지 사용되어져야 한다.


이상으로 싱글톤 패턴에 대해서 알아봤습니다.  감이 오시는지 모르겠네요. 위에서도 간략하게 설명은 했지만 어떨때 싱글톤을 사용하면 좋을지에 대해서 다시 언급해보겠습니다.

우리에게 익숙한 팝업을 예로 들어보겠습니다. 우리는 아무때나 팝업객체를 호출하여 사용할 수
있습니다. var pop = new Popup() 이렇게 말이죠 (Popup객체는 임의의 객체)

우리가 보통 사용하듯 pop.show()를 한다면 팝업이 보여지겠죠. 하지만 팝업을 띄울때마다 new Popup()을 한다면 낭비가 아닐 수 없습니다. 팝업이란 한번 보여주고 닫힐 운명인데, 한번보여줄때 객체를
생성하고 필요없으면 소멸시키고, 다시 필요하면 또 생성하고....... 너무 낭비라고 생각치 않습니까? 지금이야 당장은 필요없으니까 없애고 필요할때 다시 생성하는게 더 효율적이지 않냐고 말할 수
있습니다. 그렇다면 아래의 상황의 경우 어떨까요?
동시에 다른 객체들로부터 팝업을 오픈시켜야 한다면.... 아래의 경우겠죠.

function A(){
  ....
  var pop = new Popup()
  ....
}


function B(){
  ...
  var pop = new Popup();
  ...
}

제가 물어 보겠습니다 A.pop과 B.pop이 동일한 객체로부터 생성된 인스턴스이므로 동일한 주소값을 가질까요? 즉, 같은 인스턴스이냐고 묻는 것입니다. 답은 아닙니다. 같은 객체로부터 인스턴스를 생성하였지만, 새로 객체를 생성하였으므로 인스턴스는 새로 작성이 됩니다. 못믿으시겠다구요? 그럼 이제부터
소스로서 살펴보도록 하겠습니다.

function Test(){
 this.a = "aa";
 this.b = function(){
  alert(this.a);
 }
}

var foo = new Test();
var bar = new Test();

if(foo == bar) alert('==');
else alert('!=');


위의 코드에서 alert로 실행되는 결과는 어떤것일까요? 답은 "!=" 입니다. 각은 객체로부터 생성
되었지만 각각의 인스턴스임을 나타내고 있습니다.

Test._instance = null;
Test.getInstance = function(){
  if(this._instance == null) this._instance = new Test();
  return this._instance;
}

function Test(){
  if(Test.caller != Test.getInstance) throw new Error('There is no public constructor for MyClass');
  this.a = "aa";
  this.b = function(){
  alert(this.a);
 }
}

var foo = new Test();

위에서 배운것 처럼 싱글톤으로 객체를 호출할 준비가 되어있습니다.

그런데 new Test()로 객체를 생성하려고 하는군요. 그렇습니다. Error 객체에 의해 오류메세지가
출력됩니다.

제대로된 호출방법은 var foo = Test.getInstance(); 입니다. 그렇다면 질문을 드리겠습니다.

var foo = Test.getInstance();
var bar = Test.getInstance();

if(foo == bar) alert("==");
else alert("!=");


이렇게 되어있는 소스를 실행하면 어떤 결과가 나올거라 생각합니까? 답은 "=="가 출력됩니다.
이유는 위에서 설명드렸습니다.
 
싱글톤은 몇번을 호출해도 같은 인스턴스가 리턴되므로 객체를 재사용할 수 있고, 메모리 역시 절약할
수 있습니다. 이것이 싱글톤의 매력이겠지요. 여담이지만 자바에서의 싱글톤은 이렇게 구성하면
스레드에 의해 싱글톤이 깨질 수 있고 이를 방지하기위해 synchronized를 사용하고, 이를 더욱 확실히 하기위해 DCL(Double Checking Locking)기법을 이용하기도 합니다. 위의 예제는 아주 간단하게
만든것으로 이를 이용하고자 하시는 분은 적절히 상황에 맞게 수정하셔서 사용하시기 바랍니다.

이상으로 싱글톤 패턴에 대해서 마치고 다음 강좌를 준비하겠습니다.

posted by blankus

Javascript_pro  |  2007/06/27 00:05

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

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

만약 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

이번 강좌부터는 중급강좌입니다. 중급이라고 해서 특별한 개념은 아니고 기본적인 자바스크립트의 개념에  Gof의 디자인 패턴을 적용해보고자 합니다. 주로 외국사이트에서 설명하고 있는 것을 참고로하여 해석을
할 것이며, 필요한 부분에 대해서는 추가적인 예제를 덧붙일 예정입니다. 오늘은 가장일반적인 "생성패턴"에 대해서 알아봅시다.

설명할 디자인패턴의 첫번째는 생성 패턴(Creational Pattern) 이다.  당신이 추측한대로, 생성 패턴은 프로그램 안에서 오브젝트(Object)의 생성을 다룬다.

자바스크립트에서 오브젝트를 생성하는 일반적인 방법은 아래와 같다.

var oMyObject = new MyClass();

당신은 간단하게 당신의 클래스를 정의 할 수 있고 나중에 이것을 구체적으로 다룬다. 하지만 때에 따라선
위의 방식이 유리하지는 않을수도 있다.

아주 간단하게 생성패턴에 대해서 알아봤습니다. 다음 강좌는 싱글톤 패턴에 대해서 알아 보도록 하겠습니다.

posted by blankus

Javascript_pro  |  2007/06/26 21:55