JavaScript 패턴 - Flyweight Pattern

일반적으로 Flyweight pattern은 효율적으로 유사한 오브젝트들의 공유를 제공하여 메모리 사용을 최소화하고 고성능을 위한 소프트웨어 디자인 패턴입니다.

Ajax/Rich UI 개발의 경우 수 많은 DOM 오브젝트에 비슷한 기능을 부여하거나 수행하는 경우가 많다.  이런 경우 각 DOM 오브젝트에 메소드를 부여하거나 상속에 의한 혹은 prototype chain에 의한 레퍼런스를 통하여 기능을 수행하도록 처리합니다.
 
하지만 경우에 따라서는 매우 복잡한 DOM 오브젝트 제어가 필요하게 됩니다.  그럴 경우에 위의 패턴을 적용하면 성능 향상에 뛰어남을 보입니다.

실제로 jQuery와 ExtJS에서는 이 패턴을 적용하고 있습니다.  반대로 prototype.js 의 Element의 경우에는 $함수를 통하여 얻어온 DOM 오브젝트에 Element가 갖는 메소드 즉 down() up(), next(), previous() 등등 수 많은 메소드를 prototype에 의해서 DOM 오브젝트가 Element.down(), Element.up() 등의 메소드를 레퍼런스하게 됩니다.

IE, Safari의 경우에는 __proto__ chain메카니즘이 존재하지 않기 때문에 해당 엘리먼트에 Element 객체가 갖는 모든 메소드를 부여하는 과정을 한번 더 거치게 됩니다. <관련기사:옷장수님 블로그#Element-메소드-상속>

이 처럼 브라우저에 따라서는 수많은 오브젝트에 확장 메소드를 부여하여 수행하려고 한다면 메모리 사용과 성능면에서 뒤 떨어질 수밖에 없습니다.  

Flyweight 패턴의 경우에는 성능 향상과 메모리 사용면에서 탁월하다는 것을 느끼실 수 있을 것입니다.

간단한 그림을 통해서 Pattern을 이해해보도록 하겠습니다.

사용자 삽입 이미지


좌측은 코드의 주요 수행 과정이고 우측의 Element는 DOM 오브젝트의 기본적인 제어를 위한 공유 오브젝트입니다.  dom 프로퍼티는 Element객체 내에서 내부적으로 제어를 하게 됩니다.
예를 들어 hide 프로퍼티는 dom.style.display = ‘none’; 가 수행되는 기능을 가지고 있게 됩니다. 

좀더 섬세한 예제로 Prototype.js의 $ 함수를 예로 들어보겠습니다.
$(‘rhio’) 라는 명령문을 수행하였다면 document.getElementById(‘rhio’)를 내부적으로 수행하여 순수한 DOM 오브젝트가 반환되면 내부적으로 Element.extend가 수행되어 DOM 오브젝트에 $(‘rhio’).update(‘본 내용이 innerHTML됩니다.’); 라는 명령을 수행할 수 있게 됩니다.

즉 $ 함수를 수행할 때마다 얻어온 DOM 오브젝트에 extend하는 과정이 수행됩니다.  (Firefox의 경우 __proto__ chain에 의해서 extend 과정없이 레퍼런스가 가능하기는 합니다.)

prototype 1.6.0.2 기준으로 2543line 에 보면 $함수를 호출할 때 자동적으로 수행되는 Element.extend 수행 시

if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

명령 구문의 Prototype.BrowserFeatures.SpecificElementExtensions 에 의해서 __proto__ 메카니즘을 제공하는 브라우저인지를 체크되며 Mozilla브라우저의 경우에는 Prototype.K를 반환하고 종료됩니다.
각설하고...

반면 위의 Flyweight Pattern의 경우에 순수한 DOM은 Element.dom 프로퍼티로 레퍼런스되고 그 레퍼런스는 Element의 공유 메소드들을 통해서 제어되게 됩니다.


Source Example
var Fn = function() { };
Fn.prototype = Element.prototype;
var _fly = new Fn();

Element.Flyweight = function(dom) {
   this.dom = dom;
};
Element.Flyweight.prototype = _fly;
Element.Flyeight.prototype.isFlyweight = true;
var _flyweights = { };

Element.fly = function(el) {
  el = document.getElementById(el);
  
  if(!el) { 
     return null;
  }
  
  if(! _flyweights[‘cache’]) {
      _flyweights[‘cache’] = new Element.Flyweight();
  }
  _flyweights[‘cache’].dom = el;
  return _flyweights[‘cache’];
}; 


위의 그림과 소스를 번갈아 가면서 보시면 좀더 이해가 빠를 수 있습니다.  설명은 중요한 부분만 정리해 설명드리고 소스는 ExtJS의 Element.fly 부분을 인용하여 변경한 소스입니다.
c.f) ExtJS > Element.js 2986 line ~ 3019 line

Element.Flyweight.prototype는 implicit prototype 이 Element.prototype을 향하고Element.prototype 이 갖는 메소드들(get, hide, show 등)은 Element에 의해서 공유되게 됩니다.
Element.Flyweight function은 new 키워드를 통해 인스턴스화 될 때 Element의 공유 프로퍼티에 접근할 수 있게 됩니다.  여기까지가 Flyweight Pattern의 기본 구조라 할 수 있고 ExtJS의 경우 경우에 따라 좀더 개선된 방식까지 제공하고 있습니다.

ExtJS의 Framework이 로드되면서 생성된 변수 _flyweights에 Element.prototype을 참조하는 function 오브젝트 즉 Element.fly( )를 최초 호출되면 Element.Flyweight( )는 인스턴스화 되어 이를 저장해두고 다음 호출부터는 _flyweights의 저장된 객체에 dom 메소드만 변경하여 반환하게 됩니다.

일반적으로 DOM 오브젝트를 JavaScript로 제어하려고 할 때 일관된 메소드를 제공하는게 프레임웍의 기본 방향인 것 같습니다.  하지만 경우에 따라서는(거의 없겠지만) Image, Script의 DOM 오브젝트에는 일관된 메소드보다 확장된 메소드를 제공하고 싶은 경우거나 반대로 불 필요한 메소드를 제공하지 하지 않아야 하는 경우라면 위와 같은 패턴은 비효율적일 수 있겠습니다.

참고 :
Pro JavaScript Design Patterns [ Ross Harmes and Dustin Diaz ] 179page ~ 195page
http://en.wikipedia.org/wiki/Flyweight_pattern
http://extjs.com/forum/showthread.php?p=140648





신고
Posted by Rhio.kim
CRUD(create read update delete) Pattern정의

사용자 삽입 이미지
이번 패턴을 정리하면서 어떤 이름을 지어볼까 매우 고민 스러웠습니다.
마땅한 이름도 생각이 나질 않고...

CRUD pattern 이라고 명명 했지만 처음 이름은 XHR pattern 이였는데..
문서의 흐름과 맞지 않는 것 같기도 하고...(혼자만의 가비지...)

자세한 사항은 첨부 파일을 예제소스는 example.js 파일을..
prototype.js 를 자주 활용하다보니 예제 또한...

모티브 :
웹 페이지에서 일어나는 사용자의 단일 액션에 대응하는 일련의 프로세스를 하나의 클래스에서 구현한다.  일련의 프로세스는 사용자가 서버에 요청을 하기 위해서 클릭을 한다거나 입력을 하고 요청을 하고 그에 따른 서버 측에서 처리가 이루어지고 처리 결과를 다시 사용자의 브라우저에 통보를 하고 브라우저는 결과를 통해 사용자에게 결과를 인식 시키는 일련의 작업을 말합니다.  

목적 및 장점 :
1.    CRUD(Create, Read, Update, Delete) 인터랙션에 대한 처리와 시스템 장애에 대한 빠른 문제 파악과 대응

조건 :
1.    XHR Wrapped클래스가 존재하여야 한다. (prototype.js, dojo, jQuery, etc)
2.    XHR 오브젝트를 이용한 데이터 처리가 있어야 한다.
3.    요청을 위한 단계와 응답에 대한 처리 단계가 간단하고 명료해야 한다.

제약 :
1.    복잡한 UI 처리 및 CRUD이외의 처리가 다소 병행되어 진다면 클래스 혹은 객체가 무거워질 수 있다.

단점 :
1.    특정한 인터랙션 위한 패턴으로 확장(extend) 및 소스 재사용 면에서 용이하지 못함




중략...

요약

Ajax을 통한 개발에 있어서 사용자의 경험(user experience)은 매우 중요해졌습니다.  그만큼 사용자의 액션도 다양해졌고 매우 고급스럽게 바뀌어 가고 있습니다.  간단하게 인디케이터만 봐도 그렇습니다.  예전 Web1.0 방식에서는 웹 서버의 부하로 페이지가 열리지 않을 때 사용자는 단지 White Background 즉 아무것도 없는 하얀 백지 상태의 화면만 주시하고 있었어야 했습니다.

하지만 현재에는 인디케이터를 통해 사용자의 요청에 대한 진행 상황을 유연하게 표현함으로써 사용자의 경험을 존중해 줍니다.

이렇게 복잡해진 부분도 있지만 사용자 요청에 대한 대부분은 서버로부터 데이터를 요청하거나 입력, 갱신, 삭제에 대한 경우입니다.  요청에 대한 응답에 있어서 그 처리가 간단하고 명료한 시스템이라면 CRUD 패턴을 이용해서 하나의 요청과 하나의 응답에 대한 처리를 하나의 클래스에서 처리한다면 시스템의 장애가 발생 시 어떤 부분 즉 어떤 사용자 액션에서 발생했는지 쉽게 파악하고 대응할 수 있게 됩니다.

하지만 설계 면에 있어서 향후 시스템의 확장이 있을 경우나 사용자의 액션에 대한 처리가 복잡해지게 되면 대응하더라도 설계 구조 자체를 뒤바꿔 할 여지가 다분해 보입니다.

실제로 저는 BBS나 콘텐트의 댓글 시스템에 이전에 포스팅 한 Design by Design Pattern 과 함께 CRUD Pattern을 이용하여 개발을 했습니다.  유지 보수가 발생하지 않아서 효율 및 실무에 적용할 만한 패턴인지 증명되지는 않았습니다.

이 내용은Ajax/Rich UI의 특정한 개발을 위한 방법론에 가깝다고 봐도 무방합니다.  또한 개인적인 경험에 의한 정리이며 일반적인 시스템 설계에서 말하는 패턴의 정의와는 상이하거나 다른 의미를 갖을 수 있습니다.

신고
Posted by Rhio.kim
Javascript Optional pattern

디자인 패턴에 이미 있나? 패턴에 대한 심도 있는 연구를 해본 적이 없지만 javascript 개발을 하다 보니 자주 사용하게 되는 패턴이라 정리해봅니다.  (이미 GoF 나 POSA 에 일부분에 적용되어져 있을 수도 있습니다.)

간단하면서 이미 많은 개발자들이 이런 방식으로 개발하고 있을지 모른다고 생각한다.  외국 라이브러리 역시 이런 방식으로 개발된 라이브러리가 꾀나 있다. 거론하자니 생각이 나지 않네요. Javascript Lib 카테고리 가면 몇몇 링크가 있는데 그들 중에도 있었다.

의도 :
  하나의 클래스를 통하여 다양한 표현할 수 있다.

동기 :
  컴포넌트, 위젯 형태의 개발에 좀더 사용자 설정을 강화하여 다양한 형태의 결과를 표현하고 싶을 때, 이로 개발된 산물은 pre-config 에 대한 이해를 통해 디자이너도 쉽게 접근할 수 있도록 해보자.

sample code


위 소스에서도 알 수 있듯이 사용자는 Hash형 Object 타입으로서 pre-config를 설정하여 해당 클래스가 new 키워드로 인스턴스화 되어질 때 해당 객체의 초기 설정값에 의해 동작한거나 config의 설정된 Option을 참고하여 객체가 동작되게 됩니다.

foo 클래스는 new 키워드에 의해 인스턴스화 될때 options 이라는 파라미터를 받아서 내부의 설정값으로 동작하게 됩니다.  컴포넌트의 Positioning, Sizing, Target Element 등을 생성할때 마다 다른 형태의 결과물을 볼 수 있습니다.

간단하게 생성한 객체들의 getXY 메서드를 수행했을 때 다른 결과 즉
Foo1 의 x, y 포지션은 생성시 아무런 파라미터도 주지 않았기 때문에 [100, 200]이 출력되었고
Foo2 의 x, y 포지션은 생성시 Hash 형태의 Object에 { x:300, y:300 } 을 넘겼기 때문에 생성시 넘겼던 옵션값을 그대로 취하게 됩니다.

이는 위젯 방식의 컴포넌트 개발 시에 매우 유용하며 javascript를 이용한 Rich UI, Application 개발 시 기획에 의도를 다양하게(?) 받아들일 수 있다.

또한 디자이너나 개발자들도 pre-config에 대한 이해만 있다면 값의 설정을 통해서 쉽게 원하는 결과물을 얻을 수 있다.


신고
Posted by Rhio.kim
Data Caching Structure in Ajax(XHR) Pattern

웹에서는 수 많은 페이지에서 서버에 수 많은 데이터를 요청합니다.
Web 2.0 이전 방식에서는 페이지가 링크를 통해 이동할 때마다 서버에 불필요한 데이터 요청을 하게 됩니다.

예를 들어서 어느 블로그나 카페에 컨텐츠를 구성하는 요소 중 카테고리와 게시판이 있습니다.
우리는 이 게시판에서 요구하는 것은 게시글의 제목을 눌렀을 때 그 게시글에 대한 상세한 정보입니다.

누가 작성하였고 등록된 날짜와 시간이 언제인지 그리고 그 게시글의 내용이 무엇인지 하지만 이전 방식은 화면이 리로딩 되면서 게시글 보기 페이지로 이동되면서 좌측 카테고리 목록도 서버에서 다시 요청하는 쿼리가 수행되고 화면 인터페이스를 구성하기 위한 여러가지 쿼리들이 함께 수행되게 됩니다.

이는 Web 2.0 방식에 좀더 정확한 표현으로 Ajax 개발에 있어서 비 효율적임을 알 수 있습니다.
이로서 우리가 생각해야 하는 것은 데이터 캐싱에 대한 구조입니다.

Javascript를 이용한 간단한 예제를 들어보자면 아래의 그림과 같습니다.

사용자 삽입 이미지

기본적인 user interface 를 구성하는 코드들에 서버에 비동기 데이터 요청을 하게되는 XMLHTTPRequest 가 있습니다. 그리고 서버 사이드에서 이 비동기 요청을 받아 DBMS에 해당 요청에 대한 쿼리만 수행하고 그 결과를 응답해줍니다.

이때 화면이 리로드 되지 않기 때문에 우리는 받아온 데이터를 javascript 의 variable 즉 local storage에 hash( { key : value } ) 형태로 데이터를 저장해 놓습니다.  이는 저장된 데이터를 활용해 동일한 데이터 요청을 하지 않게 됩니다.

위에서 보는 것처럼 XMLHTTPRequest가 request가 발생되었을 때 var storage 에 기존에 요청한 데이터가 존재하는지 체크하여 있으면 Server-side Script에 요청을 하게 되고 이미 존재한 경우에는 요청 없이 local storage에 이미 있는 데이터를 그대로 활용하게 됩니다.

이 데이터 캐싱 구조는 Ajax 개발에 있어 매우 중요하고 Ajax Application을 개발하는 목적을 달성시켜주는 패턴중에 하나라고 말할 수 있습니다.

간단한 예제 소스입니다.

위의 예제처럼 storage에 서버에 요청했던 정보들을 저장해놓게 되면 재 요청이 이뤄지지 않고 기존 데이터를 그대로 활용할 수 있습니다.

하지만 단점은 한 페이지에서만 활용할 수 있으므로 화면이 리로드되거나 다른 페이지로 이동하게 되면 활용 할 수 없게 됩니다.

Firefox에서는 이를 session storage와 global storage로 storage 메커니즘을 지원하고 있습니다.

위의 예제는 session storage와 유사한 방식이며 global storage는 브라우저가 닫히기 전까지 사용할 수 있는 storage를 역할을 하고 있습니다.   하지만 현존하는 브라우저에서 모두 지원되는 메커니즘은 아닙니다.

신고
Posted by Rhio.kim
좀더 안정된 Ajax 개발 Pattern - Dynamic rendering with many HTTP Request
javascript 가 document rendering 에 미치는 영향 과는 다른 부분에서 접근했습니다.

정리하고 있는 문서중의 일부를 적어봅니다.

아래 이미지와 같은 UI를 동적으로 구현하려 할때에 Image를 포함(document component)한 Dynamic Rendering에 의해 발생하는 HTTP Requests 와 관련한 내용입니다.

사용자 삽입 이미지
좌측 이미지와 같이 "HD", "▲", "▼"는 이미지로 구성되어져 있습니다.

"HD" 이미지는 2개 하지만 정적인 페이지를 요청한 것이라면 첫번째 요청한 이미지만 Requst Result가 200(Headers and content returned)이 발생하고 그외의 이미지는 304(Content read from browser cache)가 발생하게 됩니다. Static 페이지의 경우에는 캐시를 사용하게 됩니다.

그렇기 때문에 불필요한 작은 이미지 하나 때문에 HTTP Request 를 발생하지 않습니다.

또한 우측으로 보이는
"▲", "▼" 이미지 역시 "HD" 이미지와 동일합니다.

하지만 동적으로 rendering 하는 방식은 경우(innerHTML을 통하거나, 동적 element를 사용)에 따라 이미지 개수만큼 HTTP Request가 발생합니다.

첨부한 자료는 아래의 시나리오에 의해서 나타난 결과입니다.

시나리오

  1.    createElement 를 통해 수십개의 엘리먼트를 생성합니다.
  2.    CSS에 background : transparent url(‘image url’); 속성을 갖는 className을 생성해 놓는다.
  3.    해당 엘리먼트들에 생성해 놓은 className을 부여합니다.
  4.    생성된 엘리먼트를 appendChild로 document에 rendering 합니다.


신고
Posted by Rhio.kim
사용자 삽입 이미지
오늘 愛人과 함께 백화점에 들렸습니다.
부모님 건강 식품도 알아보고 강아지 사료도 좀 보고 옷 구경도 하고 눈팅만 잔뜩하고 왔습니다.
(이거 Tech 카테고리에 "패턴 이야기" 맞는거야?)

참 연말이라 그런지 분주했습니다. 수 많은 객채들이 또다른 객채를 사기 위해 객채를 지불하고
그 대가로 객채를 받아 어느 객채에 담아서 거대한 객채를 돌아다니다 다른 객채와 대화를 나누고
객채를 한번 걸쳐보고 객채를 신어보고 객채에 상세 정보를 보고 그냥 지나가고 멀리서
다른 객채들을 처다보고 있습니다.

Javascript 백화점을 구현하시오!
200분의 시간을 드리겠습니다.

백화점엘 가면 이상하게 수면제가 있습니다. 1시간이 넘어가기도 전부터 잠이 쏟아집니다.
아무리 호화스러운 제품 신기한 제품이 있더라도 눈에 들어오지 않습니다.

수면제라는 객체는 무의식중에 생기는 객체입니다.  피로라는 객체도 함께 동반합니다.
연말에는 백화점에 혼자오는 객채는 없습니다.
이 큰 객채에서 객체들을 총 구매한 액수가 200,000원이 넘으면 50,000원 이하의 랜덤한 객체를 사은품으로
증정합니다.

이 거대한 객체는 총 100,000명의 객체를 수용할 수 있습니다.
이 객체의 매출액은 하루 68억원입니다.
(지금 무슨 소리하는 건지....) 

백화점에 가서 이런 생각을 했습니다. 과연 연말에 미x 생각이 아닐까 합니다.
이건 서론입니다.

본론으로 들어갑니다. ^-^*

실은 이이야기를 하고 싶었습니다.
화장실에 갔습니다. 늘 느끼는 거 였지만 자크를 내리기도 전에 센서가 작동하여 물이 나옵니다.
(참고로 남자 변기를 대상으로 설명합니다.)

가끔 사용자들은 자크를 내리는 속도가 느릴 수 있습니다.
그런데 미리 물은 나오고 볼일이 끝나고 사용자가 센서 앞에서 사라지면 다시 한번 물이 나옵니다.

센서 앞에서 사라지면 나오는 물은 아깝지 않습니다.
하지만 볼일을 보기도 전에 센서가 작동해서 물이 쏴하고 나옵니다.

이걸 좀더 현재 상황에 맞는 디자인 패턴에 맞춘다면 물도 아끼고 소변기의 청결 상태도 유지할 수 있을텐데
라는 생각이 들었습니다.

왜 자크를 내리기도 전에 센서에 의해서 물이 내려와야 하는지...
그전 사람이 떠날때 분명 청소가 이루어졌을텐데 말이죠..

변기 만드는 사람과 센서를 만드는 사람들이 서로의 업무 서로의 전공에 관여하지 말아야 합니다.
단 한가지의 인터페이스만 존재합니다.  센서에 의해서 소변기가 물을 틀어야 하는 것

그 왜에는 서로의 업무에 관여하면 안되겠죠.
그렇지 않고서는 지금의 방법이 최선일까요???
연초부터 이상한 생각을 했네요..

디자인 패턴은...
어느 개발자나 디자인 패턴에 맞춰 개발할 필요는 없습니다. 또한 거기에 연연할 필요도 없습니다.
그것을 나의 것으로 만들기 위해 학습은 하되 줄줄 외우려고 학습할 필요는 없습니다.
디자인 패턴이란 소프트웨어 설계에 있어 공통된 문제들에 대한 표준적인 해법과 작명법입니다.(위키 참조)

간혹 고수들의 대화를 지켜보면 이 프로젝트에는 이부분은 A패턴으로 저 부분은 B패턴으로 추가되는 부분은 C나 D패턴으로 하되 E패턴으로 변형 가능하도록 해야합니다. 모든걸 알고 있는 고수들의 패턴 대화는 알아듣기 조차 힙듭니다.

하지만 꼭 알아 들을려고 하지마시고 학습은 하세요.  열심히 코딩하고 리팩토링 작업을 거치다보면 어느새 코딩에는 패턴이 적용되 있고 누군가가 당신의 소스를 볼때 어느 패턴을 적용되었다라고 느끼게 될것입니다.
신고
Posted by Rhio.kim
자바스크립트 싱글 패턴 스토리 - I

사용자 삽입 이미지
여담 :
   참으로 싱글이 더욱 추워지는 날씨 입니다.
   내일은 싱글은 정말 속상한 하루 입니다.

   하지만 둘 일때 느끼는 추위는 싱글이 느끼는 추위보다
   더욱 춥습니다.


   그리고 더 추운 사람들은 둘이 할 수 없는
  사람들입니다.

  그런 사람들을 위해 따뜻한 손길을 뻗을 수 있는
  연말이 되었으면 합니다.




자바스크립트에서도 다양한 디자인 패턴이 가능합니다.
GoF 패턴 POSA 패턴 등 말이죠..

아마 UI 개발자 분들 중 javascript 를 이용하시는 분들은 대부분 패턴을 적용하신지 모른체 사용하고 계실꺼에요.  저도 Java 디자인 패턴 교육을 10일 동안(?) 참여했었는데요.  그 교육의 모든 예제가  Java 였습니다.  대형 프로젝트는 대부분 Java로 하니깐요..

또한 설계의 중요함을 포함해야 하는 언어이기도 하니깐요..
교육 중 다양한 패턴을 javascript 포팅을 해봤습니다. 큰 어려움은 없었습니다.






자자 서론이 길어졌습니다. 본론으로 들어가겠습니다.



위의 예제는 간단한 클래스 입니다.  foo() 를 new Operator를 통해서 foo()를 참조하는 인스턴스를
생성하였습니다.

bar와 zoo 의 constructor 는 같습니다.

하지만 인스턴스는 서로 다른 인스턴스를 같습니다.



위의 소스를 실행하보면 간단하게 알 수 있습니다.
당연히 다른 결과가 찍힐꺼라 생각됩니다.  여기서 잠시 삼천포로 빠지겠습니다.

저는 여러 예제를 봤습니다. 디자인 패턴 -> 싱글톤 도대체 이런것이 무슨 의미를 갖고 의미는 알 지언정
언제 적용해야하는 걸까? 적용해서 어떤 이점이 있을까?
또한 어떤 이점이 있고 언제 적용해야한다. ...  뭐 다양한 언어에 대해서 좋은 예시와 개념들이
많은 사이트에서 제공되고 있습니다.

하지만 몰랐습니다.  패턴이란걸 언제 쓰고 어디다 쓰고 해야하는 지!!

객체 지향에 대한 개념이 없었다는 것이었죠..  하지만 봐웠던게 도움이 많이 되었던것 같습니다.
개념을 정리하는 것이 단지 남의 예제와 예시를 보고 이해하는게 아닌 자기것으로 만드는 것
남앞에 "싱글 패턴"이 무엇이다 라고 사전적인 개념이 아닌 사전적 예시가 아닌 실제로
코드로 보여줄 수 있는 ... 역시 삼천포로 빠지는건 정리가 안됩니다...

결론은 한번 봐 놓으면 언젠간 도움이 됩니다.  아키텍쳐로 가는 것에 매우 도움이 될 것입니다.

결과는 수행해 보셨나요?

자 그러면 이해가 되지 않더라도 왜 이 글을 보고 있는지도 모르고 싱글 패턴이 먼지도 모르고 도대체
뭘 하려는 글인지 알지도 못할 지언정 "싱글 패턴이 무엇인가?" 라는 것만 꼭 올고 싶다면 위의 소스를 수행해보고 지금 이 소스를 수행해 보세요.



수행해 보셨어요?  결과는 처음 예제와는 조금 틀린 결과가 나왔네요.
당연히 new Operator 를 사용하지 않았기 때문 아니냐 라는 반문을 한다면 !!

여기서 잠깐 GoF에 나오는 싱글 패턴에 대한 소개!!
1. 접근하는 인스턴스는 오직 하나란 것이 보장이 되는 방법을 제시 해야 하며
2. 이렇게 유일한 인스턴스에 접근 할 수 있는 방법을 제공하여야 한다.

2번을 통해서 유일한 인스턴스를 제공하기 위해서 방법을 제공하였습니다.

또 하나.. 하지만 다른 누군가는 이것을 사용할때 new Operator 를 사용하면 어떻게 되느냐?
그러면 싱글 패턴이 깨지는 거 아니냐?

맞습니다. 

그렇다면 new Operator가 수행될 때 foo() 내에서 생성자를 통한 인스턴스 생성인지
아니면 싱글 패턴을 위한 방법(getInstance)에 의한 생성인지를 체크해서 new Operator를 사용할 경우에는
예외 처리를 하거나 하나의 인스턴스만 생성해 주면 되겠네요.

이 부분은 다음 시간에 다루겠습니다.

이어서 위의 소스를 잠깐 설명을 드리면 유일한 인스턴스를 제공하기 위한 메서드를 통해서
하나의 인스턴스를 생성하기 위해 new Operator 로 접근하는게 아니라

foo.getInstance() 를 통해서 접근하였습니다.
이는 foo() 의 인스턴스화 되면서 __instance__ static vairable가 설정되고 이 variable에 자신의 인스턴스가
저장됩니다.

즉 한번 생성된 foo 의 인스턴스는 null이던 this.__instance__ 에 저장되며 getInstance로 접근하게 되면
저장된 __instance__ 값을 계속해서 반환하게 됩니다.

이렇게 싱클 패턴의 조건을 만족하게 됩니다.
신고
Posted by Rhio.kim
퍼포먼스 향상을 위한 Ajax Anti Pattern
기존에 ibm에서 발표한 자료와는 조금 틀립니다.

당연히 알고 있는 부분일 수도 있지만 다시 한번 되새기고 모르시는 분들과 알지만 간과했던 부분일 수 있음을
분명히 인지하시면 좋겠습니다.

Ajax 패턴이라 하기 보다는 웹에서 javascript 로 동적 처리를 할 경우에 꼭 체크해야할 사항입니다.

사용자 삽입 이미지






위의 이미지는 jsProc.htm 파일에서 jsProc1.js 와 jsProc2.js 를 로딩하는 과정에서 발생하는 Cost에 대해서 분석했습니다. 

기본적으로 브라우저에서 js파일을 HTTP Request 할때 parallel download 가 이뤄집니다.
즉 1개의 js가 다운로드 되고 나면 그 다음에 오게될 js를 다운로드 하게 됩니다. 다른말로 block download 라고도 하는데요.

위의 이미지는 js 파일에 아무런 내용이 없을때 다운로드 되는 속도입니다.
0 byte의 js 파일을 HTTP Request 하는데에도 약 32ms 가 발생하네요. 작은 거지만
10만 모이더라도 3ms 가 발생합니다.  웹 페이지에서는 치명적입니다.


사용자 삽입 이미지






위의 내용은 jsProc1.js 에 아래의 코드를 수행하도록 처리해 놓은 것입니다. 
이는 각 모듈별로 js가 로드되면서 js가 수행하는 일이 있을때 과연 어떻게 브라우저에서는 작용을 하는지 체크하였습니다.

jsProc1.js 안의 명령들이 수행이 완료되고 나면 비로소 나머지 js파일을 로딩합니다.
jsProc1.js 의 download 시간은 313ms 가 소요되었습니다.
아무것도 없을 때에 비해 282ms 더 걸렸습니다.

이는 js 내에서 처리되는 명령들이 수행이 되고나서 다음 js 가 비로소 다운로드 됨을 의미합니다.

좀더 복합적으로 image 라들지 css, flash 등의 component 들 역시 javascript에 의해서 딜레이 되게 됩니다.

그렇기 때문에 javascript 라이브러리들은 HTML document 의 하단 부분에 넣기를 권장합니다.
그리고 js에서 페이지 로딩단계에서 처리해야 될 부분을 최소화 시켜야합니다.


TPerformance v0.0.001 - Rhio Ajax Application 2007
------------------------------------------------------------------------------
 시작 : 1197982303953/ms
 종료 : 1197982304718/ms
------------------------------------------------------------------------------
수행시간 : 765/ms
신고
Posted by Rhio.kim


티스토리 툴바