login register Sysop! about ME  
qrcode
    최초 작성일 :    2008년 04월 12일
  최종 수정일 :    2008년 04월 21일
  작성자 :    히딩크
  편집자 :    히딩크(정 석모)
  읽음수 :    31,332

강좌 목록으로 돌아가기

필자의 잡담~

봄입니다
이 강좌의 순서

강좌 시작 전 1분 12초 스피치

매우 안녕하십니다! 히딩크 입니다!

JS OOP 강좌의 마지막 편을 끝까지 기다려주신 6천900여명(한국 걜렵)의 개발자 분들께 감사의 말씀을 드립니다.

많은 분들이 기다리고 계시던 마지막 강좌가 많이 늦었습니다. 죄송하게 생각합니다. 앞으로 강좌 연재 중에는 절대로 게을러지지 않기로 약속 드리며, 우리 모두의 내공 향상에 많은 도움이 되는 양질의 강좌로 계속해서 찾아 뵐 것을 약속 드립니다.

자 그럼 인기 절정의 그룹 "닥터피쉬"의 데뷔 곡 "난 항상 여기에 있는데 뭘 그리 서두르나 이 사람아" 감상하시면서 강좌 시작 하겠습니다!


곽 부장의 편지

From : 내가 곽 부장이다! 나! 곽 부장이야!
To : 히딩크

내가 관리하는 개발팀에서 쓸 자바스크립트 프레임워크를 하나 만들고 싶네. 앞으로의 프로젝트에서 쓸 표준을 정해줄 테니 프레임워크로 말아주게!

내 부탁 들어줄 거지? 응? 응?

가만..... 내가 어제 현질을 해서 골드가 좀 많아졌는데 말이야..
근데 요즘 집사람 때문에 와우에 접속을 못해서 골드를 쓸 데가 없어.. 이거 원....

아니네, 내가 괜한 소리를 했네 그려....


히딩크의 답장

From : 히딩크
To : 얼굴만 뵈어도 아부가 절로 나오는 곽 부장님

아이코~ 하늘같으신 곽 부장님이 시키시면 하겠습니다. 안 그래도 고것이 하고 싶었었습니다. 표준만 정해 주시면 작업 시작하겠습니다.

아무쪼록 부족한 골드와 옷감만 지원해 주세요.

부장님 안 계시면 우리회사 망합니다.


왜 프레임워크를 구성해야 하죠??

사전적인 의미의 프레임워크(Framework)는 틀 구조, 얼개, 하부 구조 등등 입니다.

그렇습니다. 프레임워크는 프로그램이 개발될 수 있는 기초적인 뼈대 구조이며, 여러 가지 라이브러리들을 한데 모아서 지속적으로 재사용이 가능한 환경입니다. 이는 개발의 생산성과도 직결되는 문제입니다. 잘 설계된 .Net 프레임워크덕분에 프로그램 개발이 흥겹지 않으세요? 잘 설계된 우리만의 자바스크립트 프레임워크로 흥겨운 개발을 해 보자구욧!!

제가 이번 4부작 강좌의 마지막 4부를 프레임워크에 관련된 주제로 선정한 이유는 자바스크립트 프레임워크를 구축하여 개발 생산성을 높였으면 하는 이유에서였습니다. 또한, 프레임워크 설계 하고 모듈들을 배치하는 과정에서 무언가 얻을 수 있기 때문이기도 합니다.


Framework Specification

심심한날~ 친구가 필요한 날~ 나는 나는~ 프레임워크를 만들죠~ 뿅~~♬

이번 시간은 신나는 작품활동 시간입니다. 모두 함께 간단한 프레임워크를 만들어 보아효. 그리고, 지금까지의 세 번에 걸친 강좌에서 소개 해드린 몇 명의 친구들이 우리와 함께 할 거예요. 준비물은 자바스크립트에 대한 Love 입니다.

일단 우리가 만들 프레임워크의 이름을 지어 보도록 할게요. 제가 쓰는 강좌니까 제 마음대로 "EHGF"라고 이름을 지었으며, "Enhanced Hiddink's Generous Framework"의 약자 입니다. 굳이 한국말로 풀자면... "좀 짱인듯 한 히딩크의 관대한 프레임워크" 입니다(Generous는 '관대하다' 입니다.)

이제 무언가 있어 보이는 이름도 지어 졌으니, 프레임워크에 어떠한 기능성을 불어 넣을지 구상해 보도록 할게요. 물론 이것도 제 마음대로 이며, 제가 선정한 기능성은 다음의 목록과 같습니다.

프레임워크 기능성 목록
  • 여러 가지 모듈을 Packaging 할 Namespace 기능성
  • 서로 다른 컨텍스트 안에서 함수 참조가 가능한 Delegate 기능성
  • Page의 생과 사를 관장할 Page Lifecycle 기능성
  • 데이터의 캡슐화를 관장할 DTO(Data Transfer Object) 기능성
  • DOM Element를 콕 찝어줄 $ 기능성

Namespace 구조
  • MyFramework
    • init
    • Delegate
    • PageLifecycle
    • DTOFactory
    • DomPicker

이번 강좌는 프레임워크를 구성하는 필수요소인 Namespace 기능성을 토대로 위에서 명시한 기능성들을 하나하나 구현해 나가는 것으로 강좌를 진행 합니다. 프레임워크 완성본은 강좌 마지막 부분에 링크를 걸어 두었습니다. ^^

일단 박수 한번 치고 갑시다. /박수 /춤


자바스크립트 프레임워크 구축은 이것으로 시작한다! Namespace 구현

제일 먼저, 자바스크립트 프레임워크 구축의 시작이라고 해도 과언이 아닌 Namespace 구현을 해 보겠습니다. 자바스크립트 Namespace는 이름에서 유추할 수 있듯이 C#의 namespace와 Java의 Package와 유사한 기능성을 제공하며, 닷(.) 접근자로 각각의 계층에 존재하는 네임스페이스에 접근할 수 있습니다.

자바스크립트 Namespace를 구현하기 전에 객체 표기법에 대해 알아보아야 합니다. 자료화면 보시죠!

객체 표기법은 뭔데??
  • 객체 리터럴은 {}으로 래핑되며, 연관배열 형태이다.
  • 이름은 문자열이며, 값은 표현(Expression)이다.
  • 이름과 값은 콜론(:)으로 연결되며, 값:쌍의 구분은 쉼표(,)이다.

어? 이건 JSON이잖아!! 그렇습니다. JSON(JavaScript Object Notation) 입니다. ㅎㅎㅎㅎ

위의 표 중 첫 번째 규칙을 보면 Namespace 구현에 대한 힌트를 얻을 수 있습니다. 객체 리터럴이 {}로 래핑되며, 연관배열 형태를 가지기 때문에 얼마든지 중첩이 가능합니다.

중첩이 가능하다고?? 그렇습니다! 답은 이미 나와 있습니다. 이것들을 이용해 간단한 Namespace를 구성해 보겠습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var Root = {};

Root.Class1 = {};
Root.Class1.DoSomething = {

    MyName : "윤종대",
    AlertMyName : function(){ alert( this.MyName ); }

};

//네임스페이스 접근
Root.Class1.DoSomething.AlertMyName();

JSON을 사용해 Namespace가 매우 간단하게 구현 되었습니다. "Root"라는 최상위 Namespace가 있으며, 자식 Namespace들을 차곡차곡 배치 하였습니다.

위의 코드는 다음의 코드와 정확히 일치 합니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
var Root = {
    
    Class1 : {

        DoSomething : {

            MyName : "윤종대",
            AlertMyName : function(){ alert( this.MyName ); }

        }

    }

};

//네임스페이스 접근
Root.Class1.DoSomething.AlertMyName();

우리의 밥 아저씨가 또 한마디 하십니다. "참 쉽죠?"

자 그럼 우리가 만들 프레임워크의 첫 단추를 끼워 보도록 하죠~ 다음과 같이 말이죠~~

1
2
    //Root Namespace....
    var MyFramework     = {};

자~ 이제 루트 Namespace인 "MyFramework"가 만들어 졌습니다. 슬슬 살을 붙여 보도록 할게요~


나는 저 함수가 마음에 들어요. 사랑의 짝대기 Delegate 기능성 구현

자바스크립트에서 뭔 Delegate여? 하시는 분들 계시죠? 자바스크립트의 Delegate는 C#의 그것에 비하면 관대하지 않지만 잘 알고 쓰면 막강합니다(특히 메모리 관점에서 말이죠). C#의 Delegate를 모르시는 분들은 다음 링크의 MSDN을 참고 하세요.

  C# Programmer's Reference - delegate

우리가 구현하려는 자바스크립트 Delegate는 함수를 레퍼런스 하는 포인터 역할을 하게 됩니다. 즉, 공통으로 쓰일 함수를 한번만 정의 한 다음 여러 곳의 컨텍스트(객체)에서 그 함수를 레퍼런스할 수 있다는 얘깁니다. 또한, Delegate로 찜 당한 함수는 호출 메서드와 동일한 컨텍스트에 놓여 수행됩니다. 우리가 Xmlhttp를 사용한 Ajax 프로그래밍을 할 경우 콜백 함수에 Delegate를 지정함으로써 굉장한 메모리 절감 효과를 가져올 수 있습니다.

자바스크립트 Delegate는 3번째 강좌에서 다루었던 Function 객체의 apply 메서드를 사용합니다(함수에 전달되는 인자가 그때그때 다를 것이기 때문입니다.) 자바스크립트 Delegate는 다음과 같이 구현됩니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    //MyFramework.Delegate Namespace 구현부
    MyFramework.Delegate    = {};

    MyFramework.Delegate.createDelegate     = function( delegateInstance, pointingMethod )
    {

        return function() {

            return pointingMethod.apply( delegateInstance, arguments);

        }

    }

createDelegate 함수는 두 개의 인자를 받아 들입니다. 첫 번째 인자는 Delegate의 인스턴스이며, 두 번째 인자는 Delegate가 가르킬 함수의 인스턴스 입니다. 두 개의 인자를 받아 들여서 지정된 함수를 가리킬 수 있는 Delegate(함수) 형식으로 리턴 합니다.

자~ 이제 사랑의 작대기도 준비가 되었습니다. 히히~


내가 죽었다는 사실을 모두에게 알려주삼. Page Lifecycle 기능성 구현

사실 요 부분은 Microsoft AJAX Library에서 힌트를 얻은 녀석입니다. Microsoft AJAX Library에서는 스크립트에 pageLoad와 pageUnload 함수를 추가하면(Optional) 페이지가 로드될 때와 언로드 될 때의 이벤트를 잡아서 핸들링 할 수 있습니다. 하지만 우리는 조금 다르게 Page_Load와 Page_UnLoad을 핸들러로 사용해 보도록 하겠습니다(CodeBehind 스타일이라고 우기고 싶습니다~)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    //MyFramework.PageLifecycle Namespace 구현부
    MyFramework.PageLifecycle    = {};

    MyFramework.PageLifecycle.OnLoadHandler     = function()
    {

        if (window.Page_Load) window.Page_Load();

    }

    MyFramework.PageLifecycle.OnUnLoadHandler     = function()
    {

        if (window.Page_UnLoad) window.Page_UnLoad();

    }

예상 하셨겠지만, 매우 간단한 소스로 구현이 되었습니다. Page_Load()와 Page_UnLoad()가 정의되어 있으면 호출하고, 정의되어 있지 않다면 호출하지 않습니다.

자바스크립트 함수는 window 객체의 프로퍼티로 존재하기 때문에 if문을 사용하여 정의되어 있는지 여부를 판별합니다. 앗! 이쯤에서 스물스물 의문점이 생기는 분이 계신가요?

자바스크립트 함수가 window 객체의 프로퍼티라고??
  • 자바스크립트에서의 함수는 하나의 Type입니다(Microsoft AJAX Library에서는 함수를 Type으로 지칭합니다.) 그렇습니다~~ 자바스크립트 함수는 함수형식의 값(리터럴)일 뿐이며, window 객체의 프로퍼티로 존재합니다.

    증명해 볼까요? Dummy라는 이름의 함수 하나를 선언하신 다음에 alert(Dummy); 하시면 함수의 리터럴이 떡~ 하니 출력될 것입니다. 하지만, Dummy(); 라는 구문을 만나면 자바스크립트 엔진은 Dummy에 담겨있는 리터럴을 수행(Evaluation)할 뿐입니다.
  • 즉, 우리가 작성하는 모든 자바스크립트 코드는 부모(주로 window) 객체에 연관배열 형태(Hashtable과 같은)로 할당될 뿐입니다. 이번 강좌에서 우리가 작성하는 코드는 부모 객체(Namespace)에 할당됩니다.

호기심 해결 되었나요??

만약 Page_Load()와 Page_UnLoad()가 정의되어 있지 않으면 if문의 결과는 false가 되기 때문에 Page_Load()와 Page_UnLoad()를 호출하지 않습니다('undefined'는 'false'입니다-첫 번째 강좌 참조.)

PageLifecycle Namespace가 준비 되었으니 잠시 탐 하고 가겠습니다. 피통과 마나통 채워 주세요.


살아서 장까지 가고싶어효. DTO(Data Transfer Object) 기능성 구현

자바스크립트 함수간의 데이터 전달에 DTO(Data Transfer Object)를 사용하기 위해 팩토리 객체를 만들어 봅시다!

DTO란 데이터를 캡슐화하는 객체이며, 커스텀 필드를 입맛대로 추가해 여러 형식의 데이터를 담아서 목적지까지 안전하게 운송할 수 있습니다. 또한, 프로퍼티로 값을 담고 있기 때문에 서로 다른 함수간의 데이터 전달에 아주 효과적이며 값을 추출해 내기도 무척 쉽습니다. 함수의 인자로 DTO 하나만 받아들이면 되기 때문에 코드의 유지보수에도 무척 효과적입니다. 함수의 인자로 DTO객체 하나만 전달해 주면 되거든요~ 주고 받는 인자의 갯수를 맞춰야 할 필요가 전~~혀~~ 없습니다!!

일단 코드 보시죠!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
    //MyFramework.DTOFactory Namespace 구현부
    MyFramework.DTOFactory    = {};

    MyFramework.DTOFactory.CreateDTO    = function()
    {

        return {

                    AddProperty            : function( PropertyName )
                    {

                        this[ PropertyName ] = null;

                    },

                    DeleteProperty            : function( PropertyName )
                    {

                        if( typeof( this[ PropertyName ] ) != "function" )
                            delete this[ PropertyName ];

                    },

                    DeleteAllProperty        : function()
                    {

                        for( var PropertyName in this )
                            if( typeof( this[ PropertyName ] ) != "function" )
                                delete this[ PropertyName ];

                    },

                    GetPropertyCount        : function()
                    {

                        var Count = 0;

                        for( var PropertyName in this )
                            if( typeof( this[ PropertyName ] ) != "function" )
                                Count++;

                        return Count;

                    }

        }

    }

에~~ 쪼~~금 복잡 합니다. OOP 개념이 부족하신 분들은 조금 혼란스러우실 수도 있습니다. 하지만! 알고보면 굉장히 굉장하게 간단합니다. 단지, 미리 준비된 몇 가지의 메서드가 장착된 객체를 리턴할 뿐입니다. 리턴받은 객체에 장착된 각각의 메서드는 다음과 같은 역할을 담당합니다.

  • AddProperty 메서드 : DTO에 프로퍼티를 추가 합니다.
  • DeleteProperty 메서드 : DTO에 정의된 프로퍼티를 삭제 합니다.
  • DeleteAllProperty 메서드 : DTO에 정의된 모든 프로퍼티를 삭제 합니다.
  • GetPropertyCount 메서드 : DTO에 정의된 프로퍼티의 갯수를 반환합니다.

혹시 눈치 채신분 계신가요? 약간의 버그가 숨어 있다는 것을....

생성된 DTO에 값 타입이 아닌 함수 타입의 프로퍼티를 추가 할 경우, DeleteProperty 메서드, DeleteAllProperty 메서드, 더불어 GetPropertyCount 메서드가 제대로 동작하지 않음을 짐작할 수 있습니다. typeof( 프로퍼티 )의 결과가 'function'일 경우 건너뛰게 되어 있기 때문입니다. 무언가 다른 방법을 가미하여 문제점을 해결해야 합니다.

이 문제점의 개선은 여러분에게 맏기겠습니다! 절대 귀찮아서 이러는 것이 아닙니다. (미리 장착된 메서드에 Flag 역할을 할 자식 프로퍼티를 추가하면 되지 않을까요?)

이로써 DTO공장이 성공적으로 설립되었습니다. 오로지 신속, 친절, 정확한 DTO 기능성을 제공하며 야반도주는 있을 수 없습니다.


저는 인형뽑기 숙련도 375를 가진 블엘덕후 입니다. $ 기능성 구현

대충 눈치 채셨나요? Prototype.js의 영향으로 $()에 대해서는 모두가 알고 계실 겁니다. 바로 DOM Element를 콕 찝어내는 기능성 입니다. 간단하지만 훌륭한 기능성을 제공하기 때문에 타이핑의 노력을 줄여가며 DOM Element를 포크로 콕 찍어서 원하는 작업을 할 수 있게끔 도와주는 멋진 녀석이죠(축약 메서드라고 합니다.)

더이상 document.getElementById와 document.getElementsByName을 타이핑 하지 마세효!!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    //MyFramework.DomPicker Namespace 구현부
    MyFramework.DomPicker    = {};

    MyFramework.DomPicker.$    = function( ElementId )
    {

        return document.getElementById( ElementId );

    }

    MyFramework.DomPicker.$s    = function( ElementName )
    {

        return document.getElementsByName( ElementName );

    }

이게 끝이냐구요? 축약 메서드라니까요!!! 이제 여러분은 인형뽑기 기계의 노예.


마가렛! 제임스! 달려! 달려! 프레임워크 초기화!

이로써 제가 준비한 프레임워크의 모든 기능성을 구현 해 보았습니다. 하지만, 이게 끝이 아닙니다. 우리가 만든 프레임워크를 신나게 부려먹으려면 약간의 초기화 과정을 수행하여야 합니다. 4 개의 Delegate를 생성하고 초기화 메서드를 호출하면 모든 준비는 끝나게 됩니다~

우선, 초기화 메서드를 감상 하시겠습니다.

1
2
3
4
5
6
7
    //Init
    MyFramework.init     = function(){
    
        window.onload        = OnLoadCallBack;
        window.onunload    = OnUnLoadCallBack;             };

init() 메서드가 하는 일은 PageLifecycle의 기능성을 사용하기 위해서 onload와 onunload이벤트의 핸들러를 등록하는 일 입니다. 이벤트 핸들러 참조엔 Global 참조가 가능한 Delegate가 설정됩니다(아래의 코드에서 정의합니다.)

이로써 초기화 메서드가 완성 되었으니, 프레임워크의 초기화를 수행 해 보도록 하겠습니다. 아래의 코드는 프레임워크 바깥쪽 컨텍스트에서 수행 됩니다.

1
2
3
4
5
6
7
8
9
10
11
12
    //Delegate 설정
    OnLoadCallBack        = MyFramework.Delegate.createDelegate(
                                                    this, MyFramework.PageLifecycle.OnLoadHandler );
    OnUnLoadCallBack    = MyFramework.Delegate.createDelegate(
                                                    this, MyFramework.PageLifecycle.OnUnLoadHandler );
    
    $                            = MyFramework.Delegate.createDelegate(
                                                    this, MyFramework.DomPicker.$ );
    $s                            = MyFramework.Delegate.createDelegate(
                                                    this, MyFramework.DomPicker.$s );
    MyFramework.init();

위의 코드처럼 PageLifecycle에서 사용할 Delegate 2개와 축약 함수인 $()와 $s()을 연결시켜 줄 Delegate 2개를 생성한 후, 위에서 작성한 init() 메서드를 호출하는 것으로 우리의 프레임워크는 모든 준비가 끝났습니다.

이제 우리는 마구마구 마구마구 마구마구 마구마구 마구마구 마구마구 부려먹기만 하면 됩니다.


"좀 짱인듯 한 히딩크의 관대한 프레임워크" 소스코드 및 데모 다운로드

우리는 지금까지 간단한 우리만의 프레임워크 하나를 만들어 보았습니다. 참 재밌었죠? 소스코드와 데모는 다음 링크를 클릭하여 다운로드 하세요. 라이센스는 없으며, 마음껏 퍼가셔도 됩니다. 단, 출처만 표기 해 주세요~~

  좀 짱인듯 한 히딩크의 관대한 프레임워크 소스코드 다운로드
  좀 짱인듯 한 히딩크의 관대한 프레임워크 데모 다운로드


요약

잘 설계된 나만의 프레임워크를 만들어서 부국강병 이룩하자!


강좌를 마무리 하면서....

작년 8월에 시작한 4부작 강좌가 드디어 끝이 났네요. 그 동안의 강좌를 진행하면서 저 또한 많이 배웠습니다. 자바스크립트에 대한 새로운 깨달음을 얻었으며, 무한한 가능성에 감탄을 금치 못하고 있습니다. 자바스크립트에 대한 사랑이 매일매일 커진다고 할까요?

우리는 지금까지 오랫동안 이어져 온 자바스크립트에 대한 편견과 오해, 그리고 무관심 때문에 자바스크립트에 대한 재발견이 매우 늦어졌을 뿐입니다. 하지만, 자바스크립트는 길고 긴 시간을 인내하며 우리를 기다려 왔습니다. 이제 함께 춤출 시간입니다. 마음껏 즐기자구요~~ /춤 /춤 /춤

지금까지 자바스크립트는 한낱 귀찮은 언어이며 공부하기 창피하다고 생각해 오셨던 분들이 제 강좌로 인해 새로운 시각을 가지셨으면 하는 바램입니다. 모든 언어가 그렇듯이 자바스크립트도 노력한 만큼 대가를 돌려주는 녀석입니다. 웹 개발자에게 그 대가는 매우 크며, 욕심나는 대가입니다. 꼭 잡으시길 바랍니다.

끝으로 제 강좌가 낳은 불세출의 슈퍼스타! 김자스씨 감상하시면서 강좌 마치겠습니다. 저는 빠른 시일 안에 새로운 강좌로 찾아 뵙겠습니다. 끗~~ 뿅~~


authored by

  taeyo
  2008-07-29(14:24)
캐릭 이미지
관대한 강좌 감사합니다.~~~~
  wavstar
  2008-08-08(22:26)
캐릭 이미지
와! 좋은 강좌 입니다!
박수 짝짝짝 큰 도움이 되었습니다

수고 하셨습니다.

  bandcy
  2008-12-09(11:56)
캐릭 이미지
자바스크립트는 관대합니다
  nayha
  2009-01-21(20:27)
강좌 잘보고 갑니다 재밌네요 ^_^

 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})