반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

큰 규모의 프로젝트를 진행하려면 OOP (객체지향) 개념을 사용하는 것이 좋습니다.

이 OOP를 사용하려면 클래스를 잘 이용해야 합니다.

이번글과 다음글은 Sencha Touch 2 에서 클래스를 어떻게 사용하는지에 대해 공부해 보겠습니다.

Sencha Touch2 에서는 나름의 class system을 제공하고 있네요.

클래스를 사용하는데 여러 간편한 방법을 제공하는 것 같습니다.


오늘은 여러 규칙과 개념 위주로 정리를 하고 다음 글에서 실제로 코딩하는 방법에 대해 주로 알아 보겠습니다.


먼저 이 글을 보시기 전에 아래 Sencha Touch 2 의 class system에 대해 설명하는 동영상을 보시면 도움이 되실 겁니다.




SenchaCon 2011: The Sencha Class System from Sencha on Vimeo.



How to use classes in Sencha Touch 2  - 1 -

센차터치 2는 Ext JS 4에서 개발된 art class system을 사용합니다. 이 시스템은 providing inheritance, dependency loading, mixins, 강력한 configuration 옵션들 그리고 더 다양한 것들을 위해 자바스크립트에서 새로운 클래스를 쉽게 생성하도록 해 줍니다.

이 시스템에서 클래스는 단지 어떤 함수의 객체일 뿐이고 거기에 프로퍼티들이 첨가 됩니다. 예를 들어 여기 animal 이란 클래스가 있습니다. 이 클래스의 이름과 함수는 아래와 같이 구성할 수 있습니다.

Ext.define('Animal', {
    config: {
        name: null
    },

    constructor: function(config) {
        this.initConfig(config);
    },

    speak: function() {
        alert('grunt');
    }
});


이제 Animal이라는 클래스가 생겼습니다. 이제 각각의 animal 객체를 만들 수 있고 그 객체들은 이름을 가질 수 있고 짖을 수 있습니다. animal의 새 instance를 만들기 위해 우리는 Ext.create 를 사용하면 됩니다.

var bob = Ext.create('Animal', {
    name: 'Bob'
});

bob.speak(); //alerts 'grunt'


여기 Bob이라는 Animal을 만들었습니다. 그리고 bob에게 말하라라고 시켰습니다. 우리가 클래스를 생성하고 그것을 초기화 했고 또 그것을 더 진화시킬 수도 있습니다. 여기까지는 우리는 아직 Bob이 어떤 종류인지를 모릅니다. 이제 우리가 Human 이라는 서브클래스가 있다고 해 봅시다.

Ext.define('Human', {
    extend: 'Animal',

    speak: function() {
        alert(this.getName());
    }
});


여기 Animal을 상속받은 새 클래스가 있습니다. 이 클래스는 Animal 클래스의 모든 함수와 configuration들을 사용할 수 있습니다. 이 Human 에서는 speak 함수를 overrode 했습니다. 왜냐하면 human은 똑똑하기 때문에 grunt 하는 대신에 자신의 이름을 말 할 수 있으니까요. Human은 grunt 하지 않고 자기 이름을 말하도록 하겠습니다.

var bob = Ext.create('Human', {
    name: 'Bob'
});

bob.speak(); //alerts 'Bob'


우리는 Human 서브클래스를 추가할 때 마법같은  함수를 사용했습니다. 느끼셨겠지만 Animal 클래스에서는 getName 함수를 정의하지 않았었습니다. 어디서 이게 왔을까요? 이 class system에서는 다음과 같은 것들을 자동으로 제공하고 있습니다.

- 현재 값을 return 하는 getter 함수, 위 경우에는 getName()
- 새 값을 세팅하는 setter 함수, 위 경우에는 setName()
- setter 에 의해 call 되는 applier 함수. 이 함수는 configuration 에 변경이 있을 때 함수를 실행할 수 있도록 해 줍니다. 위 역우에는 applyName()


getter와 setter 함수들은 자동으로 생성되고 클래스 안에서 데이터를 저장할 때 사용하시기에 좋을 겁니다. 센차터치의 모든 컴포넌트는 이 class system을 사용합니다. 그리고 이렇게 자동으로 함수들을 생성해 주니까 여러분이 config를 알면 자동으로 그 값의 get과 set을 어떻게 해야 하는지도 알게 되시는 겁니다.

이 기능은 여러분들의 코드를 더 간결하게 해 줄 겁니다. 예를 들어 만약에 유저가 Bob의 이름을 바꾸고 싶어한다면 여러분은 applyName 함수를 정의하시기만 하면 됩니다. 이 함수는 자동으로 call 되는 함수이니까요.

Ext.define('Human', {
    extend: 'Animal',

    applyName: function(newName, oldName) {
        return confirm('Are you sure you want to change name to ' + newName + '?')? newName : oldName;
    }
});


위 예제에서는 브라우저의 built in confirm 함수를 사용했습니다. 이 함수는 대화창을 보여주면서 Yes 와 No 를 선택하도록 할 겁니다. applier 함수에서 만약에 false를 return 하게 된다면 이름을 바꾸는 것을 cancel 하도록 할 수도 있습니다. 위 예제에서는 유저가 Yes나 No를 선택하게 되면 거기에 맞는 새 name 이나 기존 name 이 return 될 겁니다.

만약 No를 클릭하면 Bob의 이름은 바뀌지 않겠죠.

var bob = Ext.create('Person', {
    name: 'Bob'
});

bob.setName('Fred'); //opens a confirm box, but we click No

bob.speak(); //still alerts 'Bob'


여기까지 하면 아래와 같은 클래스에 대한 아주 중요한 부분을 이미 다 알게 되신겁니다.

- 여러분들이 만드는 클래스를 포함해 모든 클래스는 Ext.define 에서 정의합니다.
- 대부분의 클래스들은 extend 신택스를 이용해 다른 클래스를 extend 합니다.
- 클래스들은 Ext.create를 사용해서 생성됩니다. 예를 들어 Ext.create('클래스이름',{어떤:'configuration'}) 이런식입니다.
- 자동적으로 생성되는 getter와 setter를 사용하기 위해 config 신택스를 사용합니다. 그러면 코드도 한결 간결해 집니다.


이 정도 되면 여러분들은 여러분의 앱에 이미 클래스들을 생성할 수 있습니다. 그런데 class system에는 몇가지 더 주의해야 할 것들이 있습니다. class system의 유용한 다른 기능들을 사용할 수 있도록 도와주는 방법들이 몇개 더 있습니다.







Dependencies and Dynamic Loading

대부분 클래스들은 다른 클래스들에 depend on 합니다. Human 클래스는 위에서 Animal 클래스를 depend on 했죠. 왜냐하면 Human 클래스에서 Animal 클래스를 extend 했으니까요. Animal 이 Human을 정의할 수 있도록 도와 준 겁니다. 가끔 여러분들은 클래스 안에 클래스를 생성해야 될 때가 있을 겁니다. 이렇게 하려면 아래 신택스대로 하시면 됩니다.

Ext.define('Human', {
    extend: 'Animal',

    requires: 'Ext.MessageBox',

    speak: function() {
        Ext.Msg.alert(this.getName(), "Speaks...");
    }
});


이런 방법으로 클래스를 생성하면 센차 터치는 Ext.MessageBox가 이미 로드 됐는지 아닌지를 체크합니다. 그래서 로드되지 않았다면 즉시 그 파일을 AJAX를 이용해서 로드 합니다.

Ext.MessageBox는 그 안에 자신이 depend on 하는 클래스들을 가지고 있을 겁니다. 그것들은 background에서 자동적으로 로드될 겁니다. 일단 모든 required 클래스들이 로드 되면 Human 클래스는 정의된거고 여러분은 people를 instantiate 하기 위해 Ext.create를 사용하기 시작할 수 있습니다. 이것은 개발자 여러분이 개발 할 대 필요한 그런 클래스들을 직접 로드할 필요없이 다 자동적으로 문제없이 로드 된다는것을 의미합니다. 그런데 production 에서는 그렇지 않습니다. 왜냐하면 인터넷을 통해서 하나하나 로드되는것은 시간이 아주 길어질 수가 있으니까요.

production 에서는 단 1개의 JavaScript 파일만을 로드할 것을 원합니다. 단지 우리의 어플리케이션이 사용할 그 클래스만 포함되면 되죠. 이것은 JSBuilder 툴을 이용해 Sencha Touch2를 사용하면 아주 쉽게 할 수가 있습니다. 이 툴은 여러분의 앱을 분석해서 여러분이 만든 모든  클래스들과 오직 여러분의 앱이 실제로 사용하는 framework class 들만 모아서 single file build를 생성하거든요. JSBuilder를 어떻게 사용하는지 좀 더 자세하게 아시고 싶으면 Building guide를 보세요.

각각의 approach는 pros와 cons를 가집니다. 이 중에 나쁜것은 말고 그 둘의 좋은 부분만 가질 수 있을까요? 정답은 yes 입니다. Sencha Touch 2 에서는 그 solution을 implement 했습니다.

Naming Conventions

클래스와 네임스페이스 그리고 파일이름과 관련해 일관된 naming convention을 사용한다는 것은 여러분의 코드를 organize 하고 structure 하고 가독성있게 유지하는데 아주 유용합니다.

1) Classes


클래스 이름들은 오직 알파벳 글자만이 포함됩니다. 숫자도 가능하지만 그것이 어떤 전문 용어가 아닌 이상 대부분의 경우 권장되지는 않습니다. 밑줄이나 하이픈 또는 다른 알파벳이 아닌 특수문자들은 사용하지 마세요.

- MyCompany.useful_util.Debug_Toolbar 같은 형식은 추천하지 않습니다.
- MyCompany.util.Base64 같은 형식은 가능합니다.


클래스 이름들은 . (dot) 을 사용해서 관련된 것끼리 패키지를 만들어서 그룹화 해야 합니다. 최소한 거기에는 한개의 유니크한 top-level 네임스페이스가 있어야 하죠.

- MyCompany.data.CoolProxy
- MyCompany.Application


top-level 네임스페이스와 실제 클래스 이름은 CamelCase를 사용해야 합니다. 다른 것들은 소문자로 하시면 됩니다.

- MyCompany.form.action.AutoLoad

Sencha Touch에서 기본적으로 지원하는 클래스가 아니면 Ext 라는 top-level 네임스페이스를 절대 사용할 수 없습니다.

Acronyms(첫글자 이니셜)은 CamelCase convention 규칙을 따릅니다.

- Ext.data.JSONProxy 대신 Ext.data.JsonProxy 를 사용합니다.
- MyCompary.parser.HTMLParser 대신 MyCompany.util.HtmlParser 를 사용합니다.
- MyCompany.server.HTTP 대신 MyCompany.server.Http 를 사용합니다.


2) Source Files


클래스 맵의 이름은 그것이 저장돼 있는 곳의 file path를 가리킵니다. 그렇기 때문에 한 파일에 한개의 클래스만 있어야 합니다.

- Ext.mixin.Observable 는 path/to/src/Ext/mixin/Observable.js 에 저장돼 있습니다.
- Ext.form.action.Submit 는 path/to/src/Ext/form/action/Submit.js 에 저장돼 있습니다.
- MyCompany.chart.axis.Numeric 는 path/to/src/MyCompany/chart/axis/Numeric.js 에 저장돼 있습니다.


path/to/src는 여러분 애플리케이션의 클래스의 경로 입니다. 모든 클래스들은 이 경로 밑에 위치합니다. 그리고 개발과 운영,보수 등을 용이하게 하기 위해 이렇게 확실하게 네임스페이스를 따라 명명합니다.

3) 메소드(Methods)와 변수(Variables)


클래스 이름과 마찬가지로 메소드와 변수 이름들도 알파벳만을 사용합니다. 숫자를 사용할 수는 있지만 특정 용어가 아닌 이상은 권장하지 않습니다. 밑줄이나 하이픈 같은 다른 특수문자들은 사용하지 마세요.

메소드와 변수 이름들은 CamelCase를 사용합니다. acronyms 에도 마찬가지로 적용 됩니다.

아래 예제가 있습니다.

사용 가능한 메소드 이름들 :

- encodeUsingMd5()
- getHTML() 대신 getHtml() 를 사용합니다.
- getJSONResponse() 대신 getJsonResponse() 를 사용합니다.
- parseXMLContent() 대신 parseXmlContent() 를 사용합니다.


사용 가능한 변수 이름들 :

- var isGoodName
- var base64Encoder
- var xmlReader
- var httpServer


4) Properties

클래스 프로퍼티 이름은 그것이 static constant일 경우를 제외하고는 메소드나 변수이름과 같은 규칙을 따릅니다. static 클래스 프로퍼티는 모두 대분자로 표시되어야 합니다.

- Ext.MessageBox.YES = "Yes"
- Ext.MessageBox.NO = "No"
- MyCompany.alien.Math.PI = "4.13"

반응형