블로그 이미지
잡초 개발자의 좌충우돌 이야기 yysvip

카테고리

분류 전체보기 (211)
Java Programing (24)
Web Programing (20)
Database (36)
Tool (46)
까칠한 IT (27)
까칠한 정보 (42)
까칠한 Strory (16)
까칠한 Project (0)
Total1,164,621
Today23
Yesterday4,565

달력

« » 2018.12
            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          

공지사항

ExtJS4 클래스 시스템의 이해

  까칠한 남자 Strory       yysvip.tistory.com       잡초 개발자 까찰한 쑤의 좌충우돌 개발 이야기

 

이전 버전인 ExtJS3에 비해 ExtJS4는 많이 달라진 모습을 보여줬다. 그 중 핵심은 클래스 시스템으로, 센차터치에도 동일하게 적용된다. ExtJS는 우리가 원하는 대부분의 기능을 클래스를 통해 지원하고 있다. 결국 이를 활용하고 새로운 것을 만들기 위해 클래스 시스템을 이해하는 것부터 시작해야 한다.

곽옥석 benneykwag@gmail.com|
한솔PNS에서 JEEE 기반 웹 시스템의 개발 및 표준화를 연구했다. 현재 프리랜서로 활동 중이며 프론트엔드 기술의 연구와 ExtJS 강사로 활약 중이다. 한국센차유저그룹(http://sencha.or.kr)에서 활동하고 있으며, 블로그(http://benney.tistory.com)를 통해 ExtJS 관련 지식을 공유하고 있다.

ExtJS는 300여 개 이상의 클래스와 이에 기반을 둔 아키텍처를 보유하고 있다. 또한 객체지향 언어를 표방한 만큼 상속, 다중상속, 이벤트를 통한 접근 등 고급 언어에서 볼 수 있는 개념들을 거의 모두 탑재해 다양하고 복잡한 애플리케이션 구현이 가능하다. 이번 시간에는 ExtJs의 새로운 클래스 시스템을 살펴보겠다.

 

 

클래스 선언과 생성
<리스트 1>은 전형적인 ExtJS 클래스 정의 및 생성방법이다.

 

<리스트 1>을 좀더 자세히 살펴보자. ① Ext.define 함수를 통해 클래스를 정의했다. 클래스 명에는 문자와 숫자가 포함될 수 있지만, 밑줄은 권장하지 않는다. 패키지를 표현하기 위해 ‘.’으로 구분했고, ‘MyClass.form.action.AutoLoad’처럼 최상위 이름과 최종 이름은 카멜케이스를 썼다. 그 외에 소문자로 표현하는 것을 권장한다. ② 상속을 받아 확장하려는 클래스를 명시한다. 앞서 말한대로 300여 개의 ExtJS의 기본 클래스를 확장, 수정함으로써 원하는 기능을 구현할 수 있다.

③ initComponent 함수 내부에는 새로 정의할 기능을 구현한다. ④ “this.callParent(arguments)”는 확장할 클래스의 initComponent 함수를 호출한다. 이는 ③에서 재정의된 기능을 확장할 클래스에 전달해 확장할 클래스와 새로운 기능을 동일한 클래스 인스턴스로 합치게 된다. ⑤ ExtJs는 정의된 클래스를 생성할 때 Ext.create 함수를 사용하고, 특정 변수에 인스턴스를 저장한다.

< 그림 1>은 <리스트 1>을 실행한 결과다.

 

 

<그림 1> 클래스 생성과 선언 실행결과

 

 

Config 기반 구성요소
ExtJS 클래스 시스템은 Config 설정 기능을 제공한다. 클래스에 Config 옵션을 정의하면 클래스 시스템은 자동으로 getter, setter, reset, apply 등 4개의 메소드를 생성한다. 이를 통해 클래스에 매개변수를 전달해 값을 설정하거나 수정할 수 있다. 새로운 클래스를 만들어 Config를 설정하자.

 

 

 

<리스트 2>를 실행하고 개발자 도구의 Console 탭에서 확인하자. 

 

<그림 2> Config 기반 구성요소 실행결과

 

 

<리스트 2>를 위부터 차례대로 살펴보겠다. ① grade, className, teacher 등 3개 Config 변수를 선언했다. ② 생성자 함수로 this.initConfig(config) 함수를 호출해 Config 변수를 초기화했다. 예제에서는 기존 ExtJS 클래스를 확장하지 않아 생성자에 this.initConfig(config)를 호출하지만, 확장하면 init Component 함수 내부에서 실행되도록 코딩해야 한다. ③ get String() 함수는 Config로 설정된 내부 변수 값을 확인하기 위해 각 Config 변수의 getter 메소드를 호출한다. 

그 다음 <리스트 3>을 통해서 apply 메소드에 대해 알아보자. 각 config 변수에 맞게 apply 메소드를 재정의했고 getString를 약간 수정했다.

 

 

<리스트 3>을 실행하면 <그림 2>와 동일한 결과가 확인된다. 이처럼 apply 메소드는 setter 메소드와는 달리 config 값을 포함한 그 밖의 내용을 설정하기 위해 사용한다.
 


상속
ExtJS는 extend 함수를 통해 상속 즉, 클래스 확장을 지원한다. 상속을 통해서 이미 존재하는 클래스 기능을 그대로 사용하면서 원하는 기능만 일부 수정하는 게 가능해진다. 이전 Config 기반 구성요소에서 완성한 ClassRoom 클래스를 사용하고 이를 확장해 Student 클래스를 만들어 보자.

 

 

세부 내용을 살펴보면, ① Student 클래스는  studentName과 studentAddress라는 2개의 Config 변수를 가진다. ② 생성자는 외부로부터 인자를 받아 현재 클래스 Config 정보를 셋팅하고 확장한 클래스 생성자도 호출하는 것으로 Config 정보를 셋팅했다.

③ this.callParent 함수는 확장한 슈퍼클래스의 함수를 호출한다. 해당 코드를 호출한 함수와 동일한 이름의 함수를 슈퍼클래스에서 호출한다. 여기서는 생성자에서 호출돼 슈퍼클래스 생성자를 호출한다.

따라서 this.callParent 호출 시 grade, className, teacher 인자를 넘긴다. 슈퍼클래스 생성자 또한 이 3개 인자를 받아 구현됐다. ④ getStudent 함수는 getString() 함수와 함께 학생정보와 교실정보를 표시한다. ⑤ getString() 함수에는 return this.callParent()만 존재한다. 이는 슈퍼클래스 getString() 함수를 호출하고 그 값을 반환하라는 의미다.

클래스 확장은 가장 강력한 기능이고 모든 코드에서 광범위하게 사용된다. 예제에서는 쉽게 설명하고자 UI가 없는 클래스를 작성했지만 대부분 UI 컴포넌트를 확장해 프로그래밍한다.

 

<그림 3> Student 클래스 실행결과

 

 

믹스인
ExtJs는 단일 클래스만 상속할 수 있다. 따라서 다중 상속을 위해선 믹스인(Mixins)을 사용해야 한다. 여러 개 클래스를 믹스인을 통해 참조하고, 참조된 클래스 기능을 사용할 수 있게 했다. 

< 리스트 5>와 같이 앞서 설명한 ClassRoom 클래스를 믹스인에 포함시키고 Ext.panel.Panel 클래스를 확장해 UI를 갖는 변형된 Student 클래스를 만들겠다. 

 

 

이전 Student 클래스와 달리 ① Ex.panel.Panel 클래스를 상속받았고, ② 믹스인 내부에 있는 classroom 변수에 Ria App.ClassRoom 클래스를 문자열로 참조했다. ③ init Component함수 내부에서는 믹스인으로 참조한 ClassRoom 클래스에 접근해 생성자를 호출하고 3개의 인자를 전달한다. ④ getStudent함수는 Student클래스의 정보와 믹스인으로 참조한 ClassRoom클래스의 정보를 보여주는 함수다.

< 리스트 6>은 실행코드다. Ext.panel.Panel 클래스를 상속받아 이전과 달리 생성자의 인자로 전달하지 않고 { } 내부에 Config 정보를 포함해 실행한다.

 

 

코드를 실행하면 <그림 4>처럼 이전과 동일한 내용이지만 Ext.panel.Panel 클래스로 인해 UI가 존재하는 클래스가 된다. 

 

 

<그림 4> 믹스인 예제 실행결과

 

 

스태틱
모든 클래스는 스태틱(statics) 변수와 메소드를 정의할 수 있다. 스태틱은 인스턴스를 생성하지 않고 접근이 가능하다. 즉 create로 생성하지 않고 ‘클래스명.변수/함수’로 접근한다. <리스트 7>을 살펴보자.

 

 

 

 

<그림 5> 스태틱 예제 실행결과

 

 

동적 클래스 로딩
동적 클래스 로딩은 ExtJS4의 새로운 기능으로 빠른 페이지 로딩보다는 유연성이 중요한 개발 환경에서 사용된다. 예를 들어 자바스크립트를 사용하기 위해서는 HTML 파일 내부에 다음과 같이 자바스크립트 파일을 포함시켜야 한다.
 
< script type=“text/javascript” src=“app.js”></script>
 
운영환경에서는 모든 자바스크립트를 병합하고 압축해 배포하지만 개발 환경에서는 클래스명으로 분리된 파일을 HTML에 포함시켜야 하는 경우가 있다. 예제를 통해 직접 확인해 보자. <그림 6>은 예제 폴더구조다.

 

 

<그림 6> 동적 클래스 로딩 예제 - 폴더 구조

 

<그림 6>과 같이 폴더를 만들고 이전 믹스인과 상속을 설명한 예제에서 ClassRoom와 Student 2개 클래스만 추출해 각기 클래스 명으로 js 파일을 생성했다. 

그 다음 <그림 7>과 같이 index.html파일을 수정한다.

 

 

<그림 7> 동적 클래스 로딩 - index.html 파일

 

app.js 파일을 <리스트 8>과 같이 코딩하고 실행하면 <그림 4>처럼 정상적으로 실행된다.

 

 

이제 동적 클래스 로딩을 테스트하기 위해 index.html 파일 내부의 ClassRoom.js와 Student.js 파일을 주석처리하고, app.js 안에 있는 Ext.onReady에 <리스트 9>처럼 Ext.Loader를 설정한다.

 

 

개발자 도구의 Elements 탭을 열고 최종 html 결과를 확인하면 Index.html 파일 내부에 있는 두 개 클래스 파일이 주석이 제거된 상태에도 이전과 같이 정상적인 결과를 보여준다. 

< 그림 8>을 확인하자. 우리가 주석 처리한 2개의 클래스가 Ext.Loader에 의해 자동으로 추가된 것을 볼 수 있다. 즉, Ext. Loader를 설정하고 Ext.require(‘RiaApp.Student’)를 통해 동적 로딩할 클래스를 명시했기 때문에 자동으로 Student.js 파일 링크가 생성됐다.

 

 

<그림 8> 개발자 도구의 실행결과

 

그런데 우리가 필요하다고 설정한 클래스는 RiaApp.Student 클래스 하나다. ClassRoom.js은 왜 있는 것일까? 이는 ExtJS 클래스 시스템이 RiaApp.Student 클래스를 실행하기 위해 필요한 다른 클래스가 무엇인지를 분석해 같이 로딩해주기 때문이다.

또 한 가지 관심 있게 봐야 할 부분은 <그림 8>과 같이 동적으로 로딩된 클래스 뒤에는 ‘_dc=일련번호’가 붙어 있다. 이 파라미터에 의해 js 파일이 브라우저의 캐시에 저장되지 않고 개발 시 수정된 내용이 바로 반영될 수 있는 것이다.

이 내용을 조금 더 자세히 알아보자. Ext.require를 주석처리하고 실행한 후 개발자 도구의 Console 창에서 결과를 확인하자. 

 

 

<그림 9> 주석처리 이후 index.html 실행화면

 

<그림 9>와 같이 Console 창 상단의 ‘Ext.onReady 상단에 Ext.require(‘RiaApp.Student’)를 추가하라’는 경고가 보이지만 프로그램은 정상적으로 구동된다. 이제 <그림 10>과 같이 개발자 도구의 Elements 탭을 확인하자. 이전과 달리 app.js 하단에 ClassRoom.js와 Student.js 파일 링크가 없어졌다. 그렇다면 왜 프로그램은 정상적으로 실행됐을까?

 

 

<그림 10> 주석 처리 후 개발자 도구 Element 탭 화면

 

이유는 실행 코드에 있다. 우리는 <리스트 8>에서 Ext.Loader를 통해 RiaApp 이하 클래스 폴더가 어디 있는지 설정해줬다. 그리고 예제를 실행하기 위해 Ext.create를 사용했다. 즉 클래스 풀 네임을 쓰고 생성할 경우 이미 RiaApp 클래스 폴더 경로인 src/RiaApp가 존재해 RiaApp.Student로 생성해도 Student 클래스에 직접 접근할 수 있다.
 
Alias
이렇게 실행에 문제가 없다면 왜 경고를 보여주는 것일까? Ext.create는 단일 클래스를 생성하는 코드로는 적합하나 여러 개 클래스를 하나의 클래스 자식으로 포함할 경우에는 부적합하다. 

이때 위젯명을 쓸 수 있다. Studen t클래스의 3번째 줄에 ‘alias : ‘widget.student’,’코드를 삽입하고 <리스트 8>을 <리스트 10>으로 대체하고 실행한다. <리스트 10>은 Ext.Viewport 객체를 생성하고 item으로 Student 클래스를 위젯명을 통해 추가한 코드다.

 

 

<리스트 9>를 실행한 결과 <그림 11>과 같이 에러가 나타나고, 비정상적으로 종료됐다. 위젯명은 폴더 경로를 포함하지 않으므로 Ext.require(‘RiaApp.Student’)의 주석을 제거하고 다시 실행한다면 문제없이 실행된다.

 

 

 

정리하며
지금까지 ExtJS의 새로운 클래스 시스템에 대해 알아봤다. 클래스는 ExtJS MVC 아키텍처의 가장 최소 단위이자 핵심이므로 잘 이해하고 있어야 한다. 다음 시간에는 ExtJS MVC 아키텍처와 이를 실무에 적용하기 위한 기술을 다루기로 한다. 강좌의 예제코드는 필자 블로그에서 다운로드할 수 있다.

 

 

'Web Programing > EXTJS' 카테고리의 다른 글

[ExtJS] ExtJS4 클래스 시스템의 이해  (0) 2014.02.13
Posted by yysvip

최근에 달린 댓글

최근에 받은 트랙백

글 보관함