728x90

요청 수가 꽤 되는 미들웨어 시스템이 있다. 그리고 이 시스템은 매번 호출 될 때마다 상세한 호출 로그를 남긴다.  마치 SQL Server의 프로파일러 마냥...

 

중요한 건 특별한 상황이 아니면 이 로그는 거의 볼 일이 없다는 것이다.

시스템이 오픈 된 초반에는 많이 참고하지만, 어느정도 안정성이 확보된 이후에는 특별히 사고나 나지 않는 이상 들여다 볼일이 거의 없다.

 

문득... 보지도 않는 이 많은 로그를 저장하는게 비효율적이라는 생각이 들었다.

그래서 보통 다른 산업에서 적용하고 있는 '표본조사'가 떠올랐다.

 

어느 제품을 생산하는 라인에서 매번 높은 수준의 전수 조사를 하게 되면 효과에 비해 비용이 너무 많이 들게 된다. 그래서 생산품 중 일부를 표본적으로 조사하는 방식이 이용되는데 로그저장도 이와 같은 개념을 접목시키면 좋겠다는 생각이 들었다.

 

즉, 매 50번째 마다 호출로그 남기기!!!

 

물론 이런 산업에서는 생산과정이 항상 일관되고 특별한 외부 요인이 개입되지 않는 환경 즉, 생산의 표준화가 보장된 상태여야 하는 전제조건이 있긴 하다.

 

따라서 표본적으로 로그 수집을 하는 경우에도 오류로그는 매번 발생할 때마다 남기는 것이 권장될 것이다.

 

결론적으로, 일반적인 로그는 표본로그로 오류 로그는 전수로그로 남기는 것이 핵심!!!

 

 

 

 

 

'프로젝트관리' 카테고리의 다른 글

개발자 칠거지악  (0) 2015.02.06
6하원칙 리더십  (0) 2014.07.09
공학의 ACE  (0) 2013.06.28
주석은 Why > What > How 순으로...  (2) 2013.06.12
애매함의 불편함  (0) 2013.06.12

OAuth 2.0 Flow

Posted in .NET Framework // Posted at 2013. 9. 5. 16:45
728x90

OAuth 2.0 스펙이 이전 버전과 비교해 덩치가 많이 커져 버린 단점(?)이 있지만, 기본 연동 모델 자체는 보다 심플해진 것 같다. 데이터의 암호화와 무결성 체크를 HTTS에 의존하기 때문에 보안을 위한 추가 장치들이 제거된, 보다 심플해진 흐름을 볼 수 있다.

 

Custom Configuration

Posted in .NET Framework // Posted at 2013. 8. 26. 15:13
728x90

닷넷 기반 응용프로그램은 (그것이 웹이든 콘솔 또는 윈도우 응용프로그램이든) 런타임에 구성 정보를 변경할 수 있도록 하는 설정파일이 존재한다.

 

웹 기반 응용프로그램의 경우 web.config, 윈도우 기반은 App.config 파일이 설정 파일 역할을 하게 된다.

 

1. Built-in AppSettings

이 설정파일에 기본적으로 제공되는 설정값 아닌 응용프로그램 자체에서 요구하는 별도의 설정 정보가 필요할 경우 대부분 <appSettings> 섹션에 의존하곤 한다.

 

<appSettings> 섹션은 '키-값' 형태의 설정 정보를 하나 이상 등록하여 사용할 수 있으며, AppSettingsReader 라는 닷넷 프레임워크가 기본으로 제공하는 리더기에 의해 엑세스 할 수 있다. 

 

* config 파일 설정:

<appSettings>
    <add key="configKeyUsingAppSetting" value="config[Value]UsingAppSetting"/>
</appSettings>

 

* conifig 값 액세스 :

AppSettingsReader appSettingsReader = new AppSettingsReader();
object valueOfAppSetting = appSettingsReader.GetValue("configKeyUsingAppSetting", typeof(string));
if (valueOfAppSetting != null)
{
     string value = valueOfAppSetting.ToString();
     Console.WriteLine(value);   //output: config[Value]UsingAppSetting

 

 

2. CustomSection Using Built-in Type

대부분의 소규모 프로젝트에서는 <appSettings> 섹션만을 사용해서 원하는 커스텀 설정값을 관리할 수 있을 것이다. 그러나 조금 더 구조적인 구분이 필요하거나 큰 프로젝트에서는 설정값의 성격에 따라 카테고리를 분리해서 관리해야 할 경우도 있다.

 

이럴 경우 제일 간단하게 접근할 수 있는 것이 내장된 타입을 이용한 커스텀 섹션을 정의하는 것이다.

이럴 경우 섹션값을 원하는 이름으로 정할 수 있기 때문에 응용프로그램의 설정 정보를 좀 더 스마트하게 구조화할 수 있게 된다.

 

커스텀 섹션을 정의하기 위해서는 <configSections> 요소에 원하는 이름의 섹션을 정의하면 된다.  이때 섹션의 타입을 닷넷 프레임워크가 제공하는 내장 타입을 지정할 수 있다. 

(사소한 주의사항은 <configSections>요소를 정의할 경우 <configuration>의 첫 번째 자식으로 위치해야 한다는 것이다)

 

실제 설정 값은 정의된 섹션의 이름으로 지정할 수 있으며 ConfigurationManager클래스를 통해 설정값을 액세스할 수 있게 된다. 다음 코드는 이러한 예를 보여준다.

 

* config 파일 설정:

<configSections>  
    <section name="mySection" type="System.Configuration.NameValueSectionHandler"/>
</configSections>

 

<mySection>
    <add key="configKeyUsingCustomSection" value="config[Value]UsingCustomSection"/>
</mySection>

 

* config 값 액세스

NameValueCollection valueOfCustomSection =

                                    (NameValueCollection) ConfigurationManager.GetSection("mySection");

string value = valueOfCustomSection["configKeyUsingCustomSection"];
Console.WriteLine(value);  //output: config[Value]UsingCustomSection

 

 

3. CustomSection Using Custom Type

보다 큰 프로젝트인 경우 설정 값 역시 복잡한 구조를 띄게 된다. 앞서 살펴본 설정 정보들은 '키-값' 형태의 단순한 구조만을 지원하므로 복잡한 구조를 수용할 수 없다.

 

간혹, 키 값 형태의 구조틀안에서 한 단계 구조를 더 첨가(?)하기 위해 구분자를 활용하기도 한다.

대략 다음과 같은 형태를 띄게 되는데, 값을 정의하는 영역에 별도의 서브키를 부여하고 구분자로 이를 잘라내서 사용하곤 한다.

<add key="key" value="subKey-value1:subKey2-value2;subKey3-value3....."/>

 

이런 형태의 사용 패턴이 잘못 되었다고는 할 수 없지만, 구조적인 측면과 유지보수성 측면에서 봤을 때 좋은 점수를 줄 수 없다. 그 이유는 설정 값의 패턴 준수를 위한 신경을 써야 하는 점과 구분자로 사용된 문자가 실제 값과 중복되지 않음이 보장되어야 하는 점 등을 들 수 있겠다.

 

좀 더 객체지향적인 접근과 유지보수성을 좋게 하기 위해서는 커스텀 객체를 기반으로 설정 정보가 동작되도록 구성하는 것이 좋다.

 

간단한 샘플을 작성해 보자.

먼저 설정 정보를 추상화 시킨 클래스를 정의한다. 여기서는 '사람'의 정보를 추상화 시킨 클래스를 정의하겠다. 이때 이 클래스가 설정 정보로 사용되기 위해서는 ConfigurationSection을 상속받아야 한다.

그리고 클래스의 멤버들은 ConfigurationProperty Attribute로 선언하며 여기서 실제 config파일의 속성으로 사용할 이름과 기본값/필수유무에 대한 속성값들을 지정한다.

 

다음 코드는 이름, 나이, 결혼유무라는 속성을 가진 PersonInfoSection 클래스를 정의하고 있다.

public class PersonInfoSection : ConfigurationSection
{
        [ConfigurationProperty("isMarried", DefaultValue = "false", IsRequired = false)]
        public bool IsMarried
        {
            get
            {
                return (Boolean)this["isMarried"];
            }
            set
            {
                this["isMarried"] = value;
            }
        }

        [ConfigurationProperty("age", IsRequired = true)]
        public short Age
        {
            get
            {
                return (short)this["age"];
            }
            set
            {
                this["age"] = value;
            }
        }

        [ConfigurationProperty("name", IsRequired = true)]
        public string Name
        {
            get
            {
                return (string)this["name"];
            }
            set
            {
                this["name"] = value;
            }
        }

}

 

이렇게 정의한 클래스 정보를 이전과 같이 커스텀 섹션에 추가하고 사용할 수 있게 된다.

* config 파일 설정

<configSections
      <section
          name="personInfoSection"
          type="CustomConfiguration.PersonInfoSection, CustomConfiguration"
       />  
  </configSections>

 

<personInfoSection name="박종명"  age="20" /> <!-- isMarried는 선택값으로 생략 가능 -->

 

* config 값 액세스

CustomConfiguration.PersonInfoSection personInfo =

  (CustomConfiguration.PersonInfoSection) ConfigurationManager.GetSection("personInfoSection");


 

Console.WriteLine(string.Format("이름:{0}, 나이{1}", personInfo.Name, personInfo.Age));

 


만일 PersonInfoSection의 멤버가 앞서 정의한 값(이름, 나이, 결혼유무)의 범위를 넘어서 또 다른 복합값을 가져야 할 경우 ConfigurationElement 상속받은 클래스를 정의하고 이 타입을 멤버로 사용하면 된다.


예를 위해서 PersonInfoSection 클래스에 자식 정보를 추가한다고 가정해 보자. 다음 코드와 같이 자식의 이름과 나이를 위한 클래스를 정의한다.


public class ChildrenElement : ConfigurationElement

{

        [ConfigurationProperty("name", DefaultValue="Arial", IsRequired = true)]

        public String Name

        {

            get

            {

                return (string)this["name"];

            }

            set

            {

                this["name"] = value;

            }

        }


        [ConfigurationProperty("age", IsRequired = true)]

        public short Age

        {

            get

            {

                return (short)this["age"];

            }

            set

            {

                this["age"] = value;

            }

        }

}


그리고 이렇게 정의한 클래스 타입을 PersonInfoSection 멤버로 사용할 수 있게 된다.

public class PersonInfoSection : ConfigurationSection

    {

       

        .........................


        [ConfigurationProperty("children")]

        public ChildrenElement Children

        {

            get

            {

                return (ChildrenElement)this["children"];

            }

            set

            { this["children"] = value; }

        }

    }

 

마지막으로 config파일에 자식 정보를 추가하고 이를 액세스 할 수 있다.

<personInfoSection name="박종명" age="20" isMarried="true">

    <children name="박길동" age="10" />

</personInfoSection>

 .....

Console.WriteLine(

 string.Format("자식이름:{0}, 자식나이{1}", personInfo.Children.Name, personInfo.Children.Age));


마지막으로 설정파일의 속성으로 사용할 클래스 멤버를 정의할 때,

ConfigurationProperty Attribute를 통해 기본 값(DefaultValue)이나 필수유무(IsRequired)를 지정할 수 있는 것과 더불어 [Type]Validator (StringValidator, IntegerValidator, ...) Attribute를 통해 유효한 문자, 숫자 범위등을 지정하는 등 좀 더 디테일한 제어가 가능하다.


마무리하며....

응용프로그램에서 필요로 하는 설정 정보를 분리하고 이를 잘 구조화해서 사용하면 코드의 직관성이나 유지보수성을 좋게 한다. 앞서 살펴본 대로 설정 정보를 구조화하는 몇 가지 방법이 있는데, 늘 사용하던 편리한 방법도 나름의 가치를 지니겠으나, 복잡한 설정 정보를 유지해야 할 경우 객체 기반으로 동작하는 코드 구성을 고민해 보길 바란다.

 

 

 

OOP in Javascript

Posted in 모바일/Javascript // Posted at 2013. 8. 16. 14:34
728x90

 

   /* 클래스, 인스턴스/클래스 변수, 메서드 */
   function Person(name){      
      this.name = name;                              //인스턴스 멤버변수(public)
      var nickname = 'pretty_' + name;         //함수 지역변수(private)  
      this.getNickName = function(){            //메서드(지역변수 엑세스)
           return nickname;
      }
    } 
   
    Person.cName = "인간";                                     //클래스 멤버변수  
    Person.prototype.age = 39;                               //인스턴스 멤버변수 추가   
    Person.prototype.getSummary = function(){        //메서드 추가
        return this.name + '(' + this.getNickName() + ')';  
    }
  
   var person = new Person('박종명');        //인스턴스 생성
   console.log(person.name);                    //인스턴스 변수 액세스
   console.log(person.getNickName());       //메서드 엑세스(메서드를 통해 함수의 지역변수 액세스) 
   console.log(Person.cName);                  //클래스 변수 액세스  
   console.log(person.getSummary());   
  
  
   /* 상속  */
   function Korean(name,age){
       Person.call(this,name);          //부모 생성자 함수 호출
       this.age = age;
   }


   Korean.prototype = new Person();        //상속


   Korean.prototype.getSummary = function(){     //오버라이딩
     return this.name + '(' + this.getNickName() + ')' + '(' +  this.age + ')';  
    }
      
   var koreanPerson = new Korean('한국사람',20);     //자식 인스턴스 생성
   console.log(koreanPerson.name);                         //부모 멤버변수 엑세스
   console.log(koreanPerson.getSummary());             //자식 오버라이딩 메서드 엑세스
  
  
   /* 객체 타입 확인 */
   console.log(person instanceof Person);
   console.log(koreanPerson instanceof Person);

'모바일 > Javascript' 카테고리의 다른 글

[AngularJS] 일주일 탐방기  (0) 2016.07.06
knockout.js  (0) 2013.11.14
함수에 대하여  (5) 2013.07.31
null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23

CSS3 3D Effect

Posted in 모바일/HTML5 // Posted at 2013. 8. 2. 18:55
728x90

CSS3 만으로 이런 UI가 가능하다뉘... 놀~라~울 따름이다

 

소스를 다운받아서 보면,

CSS3의 TransformTransition만으로 3D 효과 및 애니메이션을 구현한 것을 확인할 수 있다

 

멋쪄부러~

 

http://tympanus.net/codrops/2013/08/01/3d-effect-for-mobile-app-showcase/

Demo: http://tympanus.net/Development/3DEffectMobileShowcase/

 

참고: [CSS3] Transform   [CSS3]Transition

 

 

 

그리고 하나 더... !

 

이미지를 사용하지 않고, CSS3를 활용한 다양한 버튼 스타일 !

http://alexwolfe.github.io/Buttons/

 

 

 

'모바일 > HTML5' 카테고리의 다른 글

[HTML5 Game] Character Animation Using Sprites  (0) 2013.09.17
[HTML5 Game] Character Animation  (1) 2013.09.14
...  (0) 2013.07.23
HTML5 개발을 도와주는 도구들  (4) 2010.11.01
주요 브라우저 HTML5 지원 점수  (0) 2010.10.27

인생 노선

Posted in 일상 // Posted at 2013. 8. 2. 10:37
728x90

 

 

처음 수도권의 지하철 노선도를 보고 입이 떡... 벌어졌다

내가 부산에 있을때만 해도 노선은 한 개 밖에 없었으며 막 추가 노선을 공사하려던게 다였는데 처음 서울에 와서 본 지하철 노선은 복잡한 신경회로를 연상케 했다

 

아침 출근길에 지하철을 기다리며 문에 새겨져 있는 노선도를 찍어봤다

 

매우 복잡한 노선이지만 지하철을 기다리고 있는, 당시 나에게 필요한 노선은 오직 하나 뿐이다.

모든 사람들은 이렇게도 복잡한 노선에서 자신의 갈 길을 정확히 알고 그 노선에만 집중하는 것을 대수롭지 않게 여기며 당연하듯히 해 낸다

 

그러나 인생 노선에서는 왜 그리 헤맬 수 밖에 없는 것인가?

자신이 가야할 목적지를 정확히 정하지도 못하고 그러다보니 집중할 단 하나의 노선을 가지지도 못하니 도착할 곳에 분명치 않게 된다. 그리고 자주 복잡한 인생 노선에 압도당해서 쉬이 엄두를 내지 못하기도 한다

 

마치 목적지 없이 복잡한 지하철 한 가운데 있는 모습이다

'일상' 카테고리의 다른 글

사옥 이전  (1) 2013.10.07
미역 선물  (0) 2013.10.04
한글창제 반대 소견  (0) 2013.07.05
책 버리기  (2) 2013.06.24
경영자들이 가장 많이 쓰는 말 10가지와 그 속뜻  (0) 2013.06.19

함수에 대하여

Posted in 모바일/Javascript // Posted at 2013. 7. 31. 10:33
728x90

자바스크립트를 공부하다 보면 함수의 독특함에 많이 놀라곤 한다

이 언어가 가지는 유연함의 중심에 함수가 있으며 과히 함수기반 언어라 할 수 있다

 

먼저 모든 프로그래밍 언어에 존재하는 함수는 수학의 그것과 개념적으로 완전히 동일하다

즉 입력 값(x)에 대응하는 출력 값(y)이라는 개념 즉, f(x) = y라는 수학적 개념이 프로그래밍 언어에도 그대로 계승되었다는 것이다

 

 

 

먼저 가장 일반적인 함수 형태를 살펴 보자

//함수 정의
function Size(width,height){
    var size = width * height;
    return size;
}
       
//함수 호출
var size = Size(10,10);   
console.log(size); //100

 

function 이라는 키워드를 사용하여 함수를 정의할 수 있는데 위의 예에서는 너비와 높이를 입력 값으로 받아서 두 값의 곱 즉 사이즈를 출력(반환)하는 함수를 정의하고 호출하는 코드를 작성했다

 

return 문은 없어도 된다(이 경우 undefined가 반환된다)

대부분의 프로그래밍 언어처럼 자바스크립트 함수에서도 반드시 return으로 반환해야 하는 것은 아니다

대체로 void 함수로 정의하는데 자바스크립트에서는 반환 값의 타입을 지정하지 않기 때문에 다음 코드와 같이 return 반환이 없는 함수를 정의할 수 있다

 

function writeLog(message){
   console.log(message);
}

 

이 경우, 한가지 참고할 사항은 return 없는 함수의 호출 결과는 자동으로 undefined가 반환된다는 점이다.

return문을 통한 명시적 반환이 없는 함수가 자동으로 뱉는 undefined는 실제 프로그램에서 사용할 일은 거의 없다고 봐도 개념적으로는 기억해 두는 것이 좋다

//return문이 없는 함수 정의
function writeLog(message){
    console.log(message);
}
            
var returnValue = writeLog('Hello'); //Hello
console.log(returnValue);               //undefined

 

 

매개변수의 데이터 타입을 명시하지 않아도 된다.

심지어 매개변수의 개수가 달라도 된다

C#과 같은 언어에서는 타입 안정성을 위해 데이터 타입 제약을 강하게 둔다. 즉 사용하고자 하는 데이터의 타입이 사전에 정확히 명시되어야만 컴파일을 허용한다(C#의 var 선언도 결국 컴파일 시점에 타입이 결정된다)

 

반면, 자바스크립트는 타입 제약이 느슨한 언어이다. 앞서 코드들에서 봤겠지만 함수의 출력값은 물론 입력 매개변수에 대해서도 타입을 지정하지 않는다

 

또한 더욱 심오한(?) 것은 입력 매개변수의 개수도 개의치 않는다는 점이다. 앞서 작성했던 Size() 함수를 호출할 때 함수에 정의된 입력 매개변수 보다 더 많은 매개변수를 전달해 보자

function Size(width,height){
   var size = width * height;
   return size;
}

 

//더 많은 매개변수 전달
var size = Size(10,10,10);
console.log(size); //100

 

위 코드는 여전히 잘 동작하며 원하던 100이라는 결과를 내뱉는다.

자바스크립트에서는 함수에 정의된 것 보다 더 많은 매개변수가 전달될 경우 그것들은 무시하게 된다

 

그럼 더 적은 매개변수를 전달하면 어떻게 될까?

var size = Size(10);
console.log(size); //NaN

 

결과는 NaN이다. 오류가 아니라 정상적으로(?) 결과를 반환하는 것이다.

자바스크립트에서는 함수에 정의된 것 보다 더 적은 매개변수가 전달될 경우 나머지 값은 undefined로 할당된다.

 

즉 위의 예에서는 width = 10, height = undefined 가 되어 다음 식으로 계산된 결과를 반환한 것이다.

 

10 * undefined = NaN

 

NaN이 반환된 것은 undefined가 숫자 문맥에서는 NaN으로 평가되고 NaN과 숫자의 연산은 모두 NaN이기 때문이다

 

함수 리터럴

자바스크립트엣는 이름 없는 함수를 정의할 수 있다. 이를 함수 리터릴이라 한다. 앞서 Size 함수를 함수 리터럴로 정의하면 다음과 같다

var f = function(width,height){
       var size = width * height;
       return size;
}
            
var size = f(10,10);
console.log(size); //100

 

위의 코드를 보면 함수의 이름이 생략되었다. 여기소 var f 는 함수의 이름이 아니라 변수이며 함수 리터럴을 변수에 할당한 것이다.

 

함수 정의와 호출을 동시에

다음 코드와 같이 자바스크립트는 함수 정의와 호출을 동시에 할 수 있도록 지원한다. 아래 코드는 함수 리터럴을 선언하고 바로 호출했지만 이름을 가진 함수도 동일하게 작성할 수 있다

var result = (function(width,height){
       var size = width * height;
       return size;
})(10,10);
            
console.log(result); //100

 

 

데이터로써의 함수

앞서 함수 리터럴에서 본 것 처럼, 함수를 변수에 할당할 수 있다는 것은 함수 자체가 데이터로써의 역할을 할 수 있다는 예기가 된다.  이번 예에서는 두 개의 함수를 정의하고 이를 배열에 담아 배열로 함수를 호출하는 예를 살펴보자.

function Size(width,height){
      var size = width * height;
      return size;

   
function Sum(value1,value2){
      return value1 + value2;      
}   
  
var functionArray = new Array();
functionArray[0] = Size;
functionArray[1] = Sum;

  
for(var i = 0; i < functionArray.length; i++){
   console.log(functionArray[i](i,i));

 

위 코드는, 함수 자체를 배열로 담을 수 있다는 것으로 함수가 데이터로써의 역할을 한다는 것을 다시 한번 확인 가능하며 더불어 자바스크립트의 배열 유연성을 덤으로 눈치 챌 수 있게 하는 예이다.

 

데이터로써의 함수 특징을 볼 수 있는 마지막 예는 함수의 매개변수로 사용되는 경우이다.

function Size(width,height){
      var size = width * height;
      return size;

      
function DoubleSize(value1,value2,func){
   return func(value1,value2) * func(value1,value2);
}  
   
//함수의 매개변수로 또 다른 함수를 전달
var result = DoubleSize(10,10,Size);
console.log(result); //10000

 

C#과 같은 언어에서도 delegate라는 개념을 기반으로 한 함수(메서드)의 데이터화를 지원하지만 자바스크립트의 그것에 비하면 역사적으로 늦은 편에 속한다.

 

객체로써의 함수

C#과 Java와 같이 자바스크립트에서도 객체 기반의 프로그래밍이 가능하다.

언어적인 특징으로만 보면 자바스크립트는 생성자 함수와 프로토타입을 기반으로 한 객체 지향 프로그래밍을 지원하며 클로저를 이용한 private 멤버 구현하는 등 C#과 Java의 그것과는 다르다 할 수 있지만 상속/오버라이딩, 캡슐화와 같은 객체의 특징을 비롯해 객체에 기반한 구조적인 프로그래밍이 가능하기 때문에 객체 기반 장점을 누릴 수 있다.

 

자바스크립트에서는 클래스 생성 구문이 없다. 다만 생성자 함수를 통해 클래스와 같은 원형을 만들 수 있다

다음의 코드는 Rect라는 생성자 함수를 정의해서 객체로 사용되는 예를 보여준다.

 

이렇게 객체로 사용하는 함수를 메서드라고 부르며 메서드에는 this라는 키워드로 자신의 객체에 접근할 수 있게 된다. 내부적으로 보면 메서드는 그 메서드가 속해 있는 객체를 묵시적으로 전달받게 되는데 이 객체를 this로 접근할 수 있다는 것이다.

 

//생성자 함수 정의
function Rect(width, height){
    this.width = width;
    this.height = height;
    
    this.Size = function(){
      return this.width * this.height;
    }
}
     
//객체 생성 및 활용
var rect = new Rect(10,10);
var size = rect.Size();
   
console.log(size); //100

 

여기서 한가지 주의할 점은, 생성자 함수를 객체로 생성해서 호출(메서드 호출)하는 것이 아닌 일반 함수로 호출할 경우에는 함수 안의 this는 전역 객체를 가리키게 된다는 것이다. 다음의 예를 살펴 보자.

//생성자 함수 정의
function Rect(width){
    this.width = width;    //this는 메서드와 일반함수로 호출될 경우 대상이 달라진다
}
   
//객체(메서드)로 호출(Rect객체의 멤버 변수 width 값을 수정한다)
var rectObj = new Rect(10);
       
//일반 함수로 호출(전역 객체의 width 값을 수정한다)
var rectFun = Rect(20)
   
console.log(rectObj.width); //10          
console.log(width);            //20

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

knockout.js  (0) 2013.11.14
OOP in Javascript  (0) 2013.08.16
null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16

null과 undefined 그리고 NaN

Posted in 모바일/Javascript // Posted at 2013. 7. 29. 12:10
728x90

대부분의 프로그래밍 언어는 null 이라는 특별한 값을 지원한다.

 

ex> var temp = null;

 

이 값(null)의 의미는 '아무런 값도 나타내지 않는다'라는 의미이며 다음의 구문과는 구분된다.

 

ex> var temp;

 

즉, null 은 어떠한 유효한 값도 아니라는 의미이지 값 자체가 없다는 의미가 아니라는 말이다. 다시 말해 변수 temp에는 어떤 유효한 데이터를 담지 않을 뿐, null 값을 가진다는 의미이다. 따라서 선언만 하고 값을 할당하지 두 번재 예와는 구분되는 것이다.

 

자바스크립트는 값의 비유효성과 관련한 또 하나의 의미를 제공하는데 바로 undefined이다.

앞서 두 번째 예가 바로 undefined의 예가 되겠다. 즉 선언은 되었지만 값이 할당되지 않는 변수에 접근할 경우 undefined가 된다.

 

var temp;
console.log(temp); //선언은 되었으나 값이 할당되지 않은 변수: undefined
            
temp = null;
console.log(temp); //여전히 유효한 값은 없으나 null로 할당된 변수: null

 

결론적으로 null은 null이라는 값이 할당된 경우이지만, undefined의 경우 선언은 되었지만 아무런 값도 할당되지 않은 경우로 요약할 수 있다.

 

좀 더 나아가 객체 환경에서의 undefined를 살펴볼 필요가 있다.

선언은 되었지만 값이 할당되지 않은 변수에 접근할 경우 undefined라 했다. 이 개념은 객체환경에서도 동일한다. 즉 선언은 되었지만 값이 할당되지 않는 객체 프로퍼티 역시 undefined이다.

 

여기에 한가지 더 기억해야 할 것은, 객체 환경에서는 선언되지 않는 객체 프로퍼티도 undefined라는 점이다.

일반 변수의 경우 선언되지 않은 경우 오류(Exception)을 내뱉지만 객체 프로퍼티일 경우에는 오류가 아니라 undefined라는 점이다.

 

function TempObject(){
    this.i;       
}
   
var tempObject = new TempObject();
console.log(tempObject.i); //선언은 되었으나 값이 할당되지 않은 객체 프로퍼티: undefined
console.log(tempObject.j); //존재하지 않는 객체 프로퍼티 역시...: undefined

 

문맥에 따른 null, undefined 평가

자바스크립트는 유연한 자동 형변환이 지원되는 언어이다. 자동 형변환이란 어떤 데이터 타입이 숫자와 함께 사용될 경우 자동으로 (원래 숫자 타입이 아닌 경우에도) 자동으로 정해진 숫자로 변환되는 것이다.

여기서 숫자와 함께 사용된 경우라는 의미가 바로 프로그램 문맥상 숫자 문맥으로 평가된다는 것이다.

 

null과 undefined 역시 문맥에 따른 자동 형변환이 된다.

 

Boolean 문맥

null과 undefined는 실제로 다른 값이지만 참/거짓(Boolean)으로 평가되어야 하는 경우 모두 false로 형변환이 된다.

var temp;      
console.log(Boolean(temp)); //강제 형변환: false
   
if(!temp) //자동 현변환: undefined가 자동으로 false로 변환됨
{
   console.log('temp 변수가 false로 평가되었습니다');
}

 

숫자 문백

숫자 문맥에서는 두 값이 차이를 보이는데 null의 경우 0으로, undefined의 경우 NaN으로 변환된다.

var temp1 = null;
var temp2;    
console.log(Number(temp1)); //강제 형변환: 0
console.log(Number(temp2)); //강제 형변환: NaN
   
console.log(temp1 + 2); //자동형변환: 2
console.log(temp2 + 2); //자동형변환: NaN

 

실제로 자바스크립트 모듈을 개발할 경우, 이러한 문맥상 자동형변환의 특징을 이용하는 경우가 많다.

만일 어떤 객체에 정의된 함수의 존재여부를 식별한 후 해당 함수를 호출하고 싶을 경우 다음과 같이 작성할 수 있다.

function TempObject(){    
     this.doWork = function(){
       console.log('doWork...');
     }              
}
  
var temp = new TempObject();
if(temp.doWork){
     temp.doWork();  //조건식이 true이므로 호출됨
}
if(temp.doWork2){
    temp.doWork2(); //조건식이 false이므로 호출되지 않음
}

 

그리고 외부 모듈을 가져다 쓰는 복잡한 스크립트 환경에서 전역 네임스페이스의 충돌을 방지하기 위한 조건식으로 사용되기도 한다.

 

다음의 경우를 살펴보자. 동일한 이름의 객체를 생성하면 오류는 나지 않지만 뒤에 선언된 이름이 앞선 이름을 덮어쓰게 된다.

var someName = { i : 10 };     
console.log(someName.i);  //10
   
var someName = { i : 20 };
console.log(someName.i);  //20

 

문제는 만일 someName이라는 심벌이 외부 모듈에서 전역 네임스페이스로 이미 사용중일 경우 이름 중복은 예상치 못한 결과를 초래하기 때문에 다음과 같이 전역 네임스페이스에 동일한 심벌이 존재하는지 여부를 판단하는 것이 좋다.

var someName = { i : 10 };     
console.log(someName.i);  //10
    
if(!someName){      //만일 someName이라는 심벌이 정의되지 않았다면 새로 정의한다.   
   var someName = { i : 20 };    
}
   
console.log(someName.i); //10

 

물론 이름 충돌 방지는 도메인 네임과 같은 고유성이 보장된 이름 규칙을 사용하고 나아가 익명함수로 전역 네임스페이스를 전혀 어지럽히지 않도록 하는 기법이 존재하지만 여기서는 그 평가로 사용되는 undefined 특징을 살펴본 것이다.

 

참고로 null과 undefined의 문맥에 따른 자동 형변환 표를 정리한다.

 

 Boolean 문맥 

 숫자 문맥 

 문자열 문맥 

  null

 false 

 0 

 "null" 

  undefined

 false

 NaN

 "undefined"

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

OOP in Javascript  (0) 2013.08.16
함수에 대하여  (5) 2013.07.31
스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15

스크립트 실행 지연

Posted in 모바일/Javascript // Posted at 2013. 7. 23. 11:52
728x90

기본적으로 HTML 파서는 문서 파싱 도중에 자바스크립트를 만나면,

파싱 작업을 멈추고 자바스크립트를 다운로드하고 실행되기를 기다린다.

 

이는 덩치 큰 외부 스크립트를 문서로 삽입할 때 문서 로딩 시간의 지연을 초래하는데,

이를 해결하기 위한 메커니즘 중 하나가 deferasync 속성이다.

 

<script> 태그에 사용할 수 있는 속성으로 단어 그대로 defer은 지연, async는 비동기 특징을 지닌다.

 

보다 자세한 내용은 아래 블로그 글에서 확인할 수 있다.

 

=> script 태그의 async와 defer 속성

 

defer/async와 HTML 파서의 상호작용은 다음 포스트에서 시각적으로 확인 가능하다

=> http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution-explained/

 

그리고 이 두 속성의 브라우저 지원 여부는 다음 포스트에서 바로 확인 가능한데...

=> http://peter.sh/experiments/asynchronous-and-deferred-javascript-execution/

 

문제는 이들 속성을 지원하는 브라우저 상황이 일관되지 않아 실제 적용을 위해서는 고민이 필요하다.

 

DOM과 밀접히 상호작용하고 스크립트간 유효범위에 대한 액세스 규칙을 포함하는 등 복잡한 스크립트 환경에서는 로딩과 실행 순서에 민감할 수 있으니 자~알 보고 적용해야 할 것이다.

 

'모바일 > Javascript' 카테고리의 다른 글

함수에 대하여  (5) 2013.07.31
null과 undefined 그리고 NaN  (0) 2013.07.29
Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15
자바스크립트 상속  (0) 2013.07.12

...

Posted in 모바일/HTML5 // Posted at 2013. 7. 23. 07:52
728x90

http://www.columbia.edu/~sss31/html/html-mean.html

'모바일 > HTML5' 카테고리의 다른 글

[HTML5 Game] Character Animation  (1) 2013.09.14
CSS3 3D Effect  (0) 2013.08.02
HTML5 개발을 도와주는 도구들  (4) 2010.11.01
주요 브라우저 HTML5 지원 점수  (0) 2010.10.27
어도비, HTML5 디자인 개발툴 엣지(Edge) 공개  (0) 2010.10.26

Pie.js

Posted in 모바일/Javascript // Posted at 2013. 7. 16. 19:00
728x90

border-radius와 같은 CSS3의 새로운 효과를 IE에서도 적용되도록 해 주는 라이브러리이다.

IE6 ~ 9까지 지원되는데 다음의 CSS3 효과가 지원된다.

 

지원되는 CSS3 효과: border-radius, box-shadow, linear-gradient

 

조건부 주석을 통한 스크립트 참조  또는 htc behavior 방식 둘 중 하나를 선택해서 구현할 수 있는데, 
IE에서만 별도의 동작을 요구하기 때문에 가볍게 적용할 수 있을 듯 하다.

 

점진적 퇴보 전략 대신, IE 사용자들에게도 CSS3 경험을 선사해 주겠다면 이 라이브러리 적용을 고려해 볼 하다. 아쉬운건 좀 더 많은 CSS3 효과가 지원되지 않는다는 점이다.

 

=> http://css3pie.com/

 

 

 

 

 

'모바일 > Javascript' 카테고리의 다른 글

null과 undefined 그리고 NaN  (0) 2013.07.29
스크립트 실행 지연  (0) 2013.07.23
Zepto.js  (0) 2013.07.15
자바스크립트 상속  (0) 2013.07.12
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12

Zepto.js

Posted in 모바일/Javascript // Posted at 2013. 7. 15. 17:11
728x90

모바일 환경에서 사용할 만한 경량의 자바스크립트 라이브러리를 찾았다

 

Zepto.js 라는 라이브러리로 jQuery의 문법 구조를 그대로 유지하면서 꼭 필요한 기능만 제공하여 크기를 최소화했다.

 

모바일 환경에서 jQuery를 사용하기엔 좀 무거운 감이 있을 경우 대체안으로 적합해 보인다.

또한 UI는 jQuery Mobile과 같은 템플릿에서 벗어나고 싶지만 swipe, taphold와 같은 터치 관련 이벤트는 사용하고 싶을 경우에도 접합하다 하겠다.

 

Zepto.js는 Core 모듈과 모바일 운영체제를 식별할 수 있는 Detect 모듈, 비동기 통신을 위한 Ajax 모듈, 에니메이션 효과를 위한 Effects 모듈, 터치 이벤트 지원을 위한 Touch 모듈 등으로 구성되어 있다.

 

=> http://zeptojs.com

 

 

'모바일 > Javascript' 카테고리의 다른 글

스크립트 실행 지연  (0) 2013.07.23
Pie.js  (0) 2013.07.16
자바스크립트 상속  (0) 2013.07.12
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12
평점에서 별표 마킹  (0) 2012.11.16

자바스크립트 상속

Posted in 모바일/Javascript // Posted at 2013. 7. 12. 18:02
728x90

객체 지향 언어의 면모를 여실히 보여주는 자바스크립트 상속! 다형성!

좋구먼~ ㅎㅎㅎ


넌 너무 유연해~~


var Polygon = function(){

    var self = this;

    self.type = "Polygon";    

    self.commonDo = function(){

        console.log("commonDoing...");

    };

    self.draw = function(){

        console.log("draw " + self.type);

    };

};


var Square = function(){

  var self = this;

  self.type = "Square";

  self.draw = function(){                              //오버라이딩

      console.log("draw " + self.type); 

  };

  self.squareDoing = function(){

    console.log("squareleDoing...");  

  }

};

Square.prototype = new Polygon();         //상속



var Triangle = function(){

  var self = this;

  self.type = "Triangle";

  self.draw = function(){                              //오버라이딩         

      console.log("draw " + self.type);

  };

  self.triangleDoing = function(){

    console.log("triangleDoing...");  

  }

};

Triangle.prototype = new Polygon();       //상속


....


var obj1 = new Square();

obj1.commonDo();

obj1.draw();     

obj1.squareDoing();       

var obj2 = new Triangle();

obj2.commonDo();

obj2.draw();

obj2.triangleDoing();          

console.log(obj1 instanceof Polygon);

console.log(obj2 instanceof Polygon);



prototype.js를 이용하면 보다 가독성 높은 상속 코드를 구현할 수 있다. 아래 코드는 prototype.js를 사용해서 이전 코드와 동일한 클래스 및 상속 구조를 구현한다

var Polygon = Class.create({

    initialize: function(){

        this.type = "Polygon";

    },  

    commonDo : function(){

        console.log("commonDoing...");

    },

    draw : function(){

        console.log("draw " + this.type);

    }

});


var Square = Class.create(Polygon,{

  initialize: function(){

        this.type = "Square";

  },  

  draw : function(){               

      console.log("draw " + this.type); 

  },

  squareDoing : function(){

    console.log("squareleDoing...");  

  }

});



var Triangle = Class.create(Polygon,{

  initialize: function(){

        this.type = "Triangle";

  },

  draw : function(){               

      console.log("draw " + this.type); 

  },

  triangleDoing : function(){

    console.log("triangleDoing...");  

  }

});



'모바일 > Javascript' 카테고리의 다른 글

Pie.js  (0) 2013.07.16
Zepto.js  (0) 2013.07.15
ProcessingJS, 자바스크립트 Canvas 라이브러리  (0) 2013.07.12
평점에서 별표 마킹  (0) 2012.11.16
자주 쓰는 jQuery 기능 - 이벤트 편  (0) 2011.08.04
728x90

jQuery 개발자인 John Resig이 개발한 자바스크립트 기반의 그래픽 라이브러리로, Processing Java Library를 HTML5 Canvas 환경에 맞게 포팅한 것으로 각종 그래픽 작업 및 효과를 구현할 수 있다. 


기존 Java 라이브러리와 동일한 구문을 사용하기 때문에 기존 사용자는 추가 노력 없이 쉽게 사용할 수 있다는 장점이 있다. 안타깝게도 개인적으로 자바 개발자가 아니라 접해 본 경험이 없어 아쉽다.


또한 HTML5의 Canvas 기능을 랩핑한 것이라 Canvas API를 직접 다루지 않고 쉽고 잘 추상화된 Processing 구문만으로 훌륭한 그래픽 효과를 줄 수 있다. 


다음의 공식 사이트에서 라이브러리와 데모 및 레퍼런스를 얻을 수 있다

=> http://processingjs.org/

 

간단한 사용 예를 다음과 같다.


먼저 Processing 구문의 그래픽 코드를 pde 파일로 준비한다.

 

* basic-example.pde (http://processingjs.org/learning/ 에서 발췌)

// Global variables

float radius = 50.0;

int X, Y;

int nX, nY;

int delay = 16;


// Setup the Processing Canvas

void setup(){

  size( 200, 200 );

  strokeWeight( 10 );

  frameRate( 15 );

  X = width / 2;

  Y = width / 2;

  nX = X;

  nY = Y;  

}


// Main draw loop

void draw(){  

  radius = radius + sin( frameCount / 4 );

  

  // Track circle to new destination

  X+=(nX-X)/delay;

  Y+=(nY-Y)/delay;

  

  // Fill canvas grey

  background( 100 );

  

  // Set fill-color to blue

  fill( 0, 121, 184 );

  

  // Set stroke-color white

  stroke(255); 

  

  // Draw circle

  ellipse( X, Y, radius, radius );                  

}


// Set circle's next destination

void mouseMoved(){

  nX = mouseX;

  nY = mouseY;  

}



다음으로 processingJS 라이브러리르 참조하고 pde 파일을 Canvas로 연결하는 HTML 파일을 생성한다. 


* Test.html

<!DOCTYPE html>

<html>

<head>

  <script src="processing-1.4.1.js"></script>

</head>

<body> 

  <canvas data-processing-sources="basic-example.pde"></canvas>  

</body>

</html>


참고로 pde 파일을 웹 서버가 이해할 수 있도록 MIME 타입 설정을 잊지 말자.


물론 pde 파일이 아닌 스크립트만으로도 가능하다. 다음과 같이...

<!DOCTYPE html>

<html>

<head>

  <script src="processing-1.4.1.js"></script>

</head>

<body> 

  <script type="application/processing">

  // Global variables

  float radius = 50.0;

  int X, Y;

  int nX, nY;

  int delay = 16;

  

  // Setup the Processing Canvas

  void setup(){

    size( 200, 200 );

    strokeWeight( 10 );

    frameRate( 15 );

    X = width / 2;

    Y = width / 2;

    nX = X;

    nY = Y;  

  }

  

  // Main draw loop

  void draw(){  

    radius = radius + sin( frameCount / 4 );

    

    // Track circle to new destination

    X+=(nX-X)/delay;

    Y+=(nY-Y)/delay;

    

    // Fill canvas grey

    background( 100 );

    

    // Set fill-color to blue

    fill( 0, 121, 184 );

    

    // Set stroke-color white

    stroke(255); 

    

    // Draw circle

    ellipse( X, Y, radius, radius );                  

  }

  

  // Set circle next destination

  void mouseMoved(){

    nX = mouseX;

    nY = mouseY;  

  }

  </script>

  <canvas></canvas>  

</body>

</html>

 

다양한 데모를 직접 체험해 보고 싶으면 http://processingjs.org/download/ 에서 Examples zipped를 다운받아서 로컬 브라우저로 바로 확인 가능하다


'모바일 > Javascript' 카테고리의 다른 글

Zepto.js  (0) 2013.07.15
자바스크립트 상속  (0) 2013.07.12
평점에서 별표 마킹  (0) 2012.11.16
자주 쓰는 jQuery 기능 - 이벤트 편  (0) 2011.08.04
자주 쓰는 jQuery 기능 - 셀렉터(Selector) 편  (2) 2011.08.03

간단한 C# 문법 Quiz

Posted in .NET Framework // Posted at 2013. 7. 11. 16:16
728x90

Name 이라는 속성을 가진 Person 클래스가 있다고 가정한다

 

그리고 다음과 같이 ChangeName 메서드를 호출한 후 콘솔에 찍히는 Name 값은??

ChangeName(Person person)
{
        Person newPerson = new Person();
        newPerson.Name = "개명";            
        person = newPerson;
}

 

.....

 

Person person = new Person();
person.Name = "본명";
ChangeName(person);

 

Console.WriteLine(person.Name);  //Name 값은??

 

간단하지만 자칫 헷갈리기 쉬운 문제다.

 

그럼. 이 질문은 어떤가?

 

질문> 객체를 '참조에 의한 전달'로 해야 할 경우는 언제인가??

 

객체 자체는 참조타입으로 메서드 호출 시에도 그 참조가 전달된다. 그런데 명시적으로 참조로 전달해야 할 경우란 어떤 경우인가 하는 것이다.

 

사실 이 문제는 과거에 한번 정리했던 적이 있다.

=> 참조형식을 참조로 전달???

 

중요한 멘트를 하나 남기고 싶어서 다시 끄적여 본다

 

"참조값 자체는 값에 의해 전달 된다"

 

좀 더 풀어서 적어보면, "참조 자체는 값에 의해 전달된다"

더 풀어보면 "참조에 의한 전달에서 참조 값 자체는 값에 의한 복사가 이뤄진다"

 

말 장난 같은 이 말은, 사실 혼돈을 정리하는 핵심 문구이다. ㅎㅎ

'.NET Framework' 카테고리의 다른 글

OAuth 2.0 Flow  (0) 2013.09.05
Custom Configuration  (6) 2013.08.26
나에게 유용했던 닷넷 서적  (2) 2013.07.04
WCF Service Reference Error(Cannot import wsdl:portType)  (0) 2013.07.03
IOC using Ninject  (0) 2013.06.18