'안성현'에 해당되는 글 46건

  1. 2012/01/15 단위테스트를 보다 쉽게, JUnit 을 사용하자.
  2. 2011/12/26 우리는 어떻게 한글을 사랑할 수 있을까?
  3. 2011/11/30 [JAVA] HashTable 을 이용한 로컬캐쉬(LocalCache)
  4. 2011/05/07 [iOS] 자동 개월수 계산 코드
  5. 2011/05/03 한우찾기 v2.0 프로모션 동영상
  6. 2011/05/03 [App] 한우찾기 v2.0 출시
  7. 2011/02/04 문득.. 그런생각이 들었다.
  8. 2010/11/18 [C#] 윈폼 컨트롤 박스 없이 마우스 드래그앤 드롭으로 이동.
  9. 2010/03/19 [Windows Phone7] mini Browser Sample 분석
  10. 2010/03/18 [Windows Phone 7] 윈도우 폰 7 개발 Getting Started

단위테스트를 보다 쉽게, JUnit 을 사용하자.

단위 테스트를 어떻게 구성해야 할까에 대해서 생각해 볼 경우가 종종 있는것 같다. 실제로 필자가 속한 조직에서는 아직 단위테스트에 대한 필요성을 인지 하지 못한것인지는 모르겠지만, 아무튼 새롭게 프로토타입(Prototype)을 구성중인 자바 기반의 문서 이미지 추출 프로젝트에서는 클린코드와 단위테스트를 필수로 포함시키기로 하였다. 


컴퓨터 프로그래밍에서 유닛 테스트란 소스 코드의 특정 모듈이 의도된 대로 정확히 작동하는지 검증하는 절차다. 즉, 모든 함수와 메소드에 대한 테스트 케이스(Test case)를 작성하는 절차를 말한다. 이를 통해서 언제라도 코드 변경으로 인해 문제가 발생할 경우, 단시간 내에 이를 파악하고 바로 잡을 수 있도록 해준다. 이상적으로, 각 테스트 케이스는 서로 분리되어야 한다. 이를 위해 가짜 객체(Mock object)를 생성하는 것도 좋은 방법이다. 유닛 테스트는 (일반적인 테스트와 달리) 개발자(developer) 뿐만 아니라 보다 더 심도있는 테스트를 위해 테스터(tester)에 의해 수행되기도 한다.



단위 테스트에 대해서 막연히 알고 있었고, 필요하다고는 느끼고 있었지만 처음 도입해 보는 과정에서 여러가지 시행 착오가 있었다. 

가장 큰 문제는 단위테스트 코드는 어디에 위치하는것 인가? 하는 부분이었다. main함수에서 해야하는 것인지(이 경우, 객체를 생성해야 하고 publc 함수 밖에 테스팅 할수 밖에 없다.) ,  해당 클래스 내 함수가 있는 위치에서 따로 뽑아서 해야하는것인지(이럴경우, 객체를 만들 필요가 없고, private 함수까지 테스팅을 할 수 있다.) 고민되는 부분이 있었다. 

또 다른 문제는 명명법에 대한 문제인다. 같은 함수내에 단위 테스트에 대한 코드를 둔다면, 실제 실행 함수와 어떻게 구별할 것인가? 함수 앞에 test_ 접두어를 붙일수도 있지만, 더 큰 문제는 나 외에 다른 동료들도 이러한 내용을 강제하고 지키도록 동의를 해야한다는 것이다. 그렇지 않는다면, 소스코드는 실제 사용하는 부분과 그리고 테스트 코드 부분을 구분 할 수 없게 되는 문제가 있다. 

처음에는 main() 함수가 있는 클래스에 static 함수로 다른 클래스의 실제 사용하는 함수를 테스팅 하는 코드를 넣는 방식으로 하였다. 이 경우 문제점은 여러가지 함수를 테스팅하기 위해서는 main()에서 다양한 static 테스트 함수들을 써야 한다는 점이다. 그래서 좀 불편한것 같았다. 

그러던 중 JUnit 에 대해서 알게되었다. 일단 써보면서 특징을 설명하겠다

일단 JUnit을 사용하기 전에,

빌드 패스(Build Path)에서 추가 라이브러리(Add Library)를 눌러서 JUnit을 추가
하도록 하자. 필자는 JUnit3를 설치하였다. 자 그러면, 이제 JUnit 을 본격적으로 사용해 보자. 

빌드경로에서 라이브러리 추가

 

JUnit3 선택



이클립스의 File의 New를 눌러서 JUnit Test Case를 누르면 테스트 케이스를 만들수 있다. 아래의 화면과 같이 나오게 되면 일단 하단에서 New JUnit3 Test Case를 선택한다. 우리는 앞에서 JUnit3 라이브러리를 추가했기 때문에 이것을 선택해 주면된다. 그리고 나서 되도록 현재 만드는 단위 테스트가 속할 패키지를 지정해 준다. 되도록이면 지정하는 것이 좋다. 왜냐하면 JUnit Test Case 역시 하나의 클래스 파일이기 때문에 패키지로 구분해 주는 것이 가독성 측면에서 좋다.

JUnit Test Case 추가




패키지 지정을 했으면, 이름(name)을 지정해 주자. 일반적인 클래스 이름이라고 생각하시면 되는데 이때에 일반 클래스를 대상으로 테스트 하는 것이기 때문에 이름에서 어떤 클래스를 테스트 하고 있음을 나타내는 동시에, 이 클래스가 유닛테스트 클래스라는 것을 알려주자. 예를 들어, 내가 ExtractorImage 라는 클래스에 대한 유닛테스트를 만든다고 하면, UnitTest_ExtractorImage 이런식으로 UnitTest_ 라는 접두어를 통해서 해당 클래스가 유닛테스트 클래스 임을 알려주자. 

마지막으로는 어떤 클래스에 대한 유닛테스트 인지를 설정하는 부분으로 제일 아래에 있는 class under test 에서 browse를 눌러서 테스트 하려는 클래스를 적어주면 알아서 찾아준다. 자, 입력을 다 했으면, 이제 Next를 누르면 앞에서 입력한 테스트 대상 클래스의 함수들이 나온다. 보시면 알겟지만, Public 함수에 대해서만 테스트를 할 수가 있다. 이 단계에서 테스트를 할 함수를 체크를 한다. 체크를 다했으면 기본적은 단위 테스트의 구성이 끝나고 해당 단위테스트 클래스가 만들어 지는것을 볼 수가 있다. 

테스트 대상 클래스 지정



테스트 할 함수 지정



만들어진 단위 테스트 클래스의 내부를 보자. 


JUnit 테스트 결과



우리가 앞에서 지정했던 함수에 대해서 미리 만들어져 있다. 그런데 형태를 보면, public void testExtractorManager() 이런 형태로 원래 함수 test라는 접두어를 붙여서 표시를 하였다. 일단 한번 테스팅을해 보자 테스팅을 하면 이전과 다르게 오른쪽에 JUnit 테스트에 대한 결과를 보여주는 창이 나온다. 보시면 Runs, Errors, Fails 가 있는데 처음 생성을 하면 아래처럼 나오기 때문에 현재는 Fails:4 라고 표시가 되어 있다. 

public void testExtractText()
{	
fail("Not yet implemented");
}


이제 구현을 해 보자. 일단 각각의 테스트 함수에다가 필요한 테스트 코드들을 넣어준다. 만약 테스트 함수 외의 함수를 넣고 싶다면, test 접두어를 붙이지 않은채 코드를 넣으면 된다. 예를 들어 testExtractImage() 함수에서 특정 디렉토리 경로를 가져오는 함수를 호출해야 한다면, 


private String GetTestDocPath()
{	
File dir = new File("");	
return dir.getAbsolutePath() + File.separator + test_document;
}

public void testExtractImage()
{			
String doc_dir_path = GetTestDocPath(); 
}



이런식으로 GetTestDocPath()를 써주면 된다. 대신에 이 부분은 test접두어로 시작되지 않기 때문에 JUnit test를 실행 시킬때 결과에 표시되지 않는다. 그렇다면, 검사 대상 클래스의 내용이 추가 된다면 어떻게 해야 할까? 다시 앞의 단계를 반복해야할까?

수동으로 JUnit 테스트의 결과에 포함되는 테스트 함수를 추가 시키는 방법은 간단하다. 어떤 테스트 하려는 함수를 만들고 그 함수이름의 제일 앞에 test 접두어를 붙여주면 된다. 예를들어, testExtractImage1() 을 만들어 주고 테스트를 돌려보면 아래와 같은 결과를 얻을 수가 있다. 

수동 테스트 함수 추가 결과



추가된 함수가 결과에 포함된 것을 볼수가 있다. 이렇게 하면 대상 클래스의 내용이 변하더라도 능동적으로 테스트 코드에 추가할 수가 있다. 


자, 이제 다 구현을 하고 JUnit을 돌려보자. 필자가 생각하는 JUnit의 가장 큰 장점은 해당 함수에 대한 실행 시간을 표시해 줄수 있다는 것이다. 사실 프로그래머는 성능 측정에 대해서 자유로울 수가 없는데 JUnit 에서는 이런 부분을 쉽게 해결해 준다. 하나의 함수에 대한 실행 시간을 알려줌으로써, 어떤 부분이 병목을 가지고 있는지 테스트 케이스를 구성함으로써, 쉽게 알수가 있다. C 언어에서 처럼 시간을 측정하는 부분을 넣을 필요가 없다.(사실 이 부분은 소스코드를 더럽히기도 하고, 다른 여러가지 툴이 있을것이라 생각된다.)


결론. 

JUnit을 꼭 사용하자. 
그리고 성능 측정을 하고, 개선을 하자. 
그리고 쉽게 유지보수 할수 있는 여지를 주자. 
마지막으로. 쉽게 인수인계 할수 있을것 같다. 



저작자 표시 비영리 변경 금지
Technique/etc 2012/01/15 16:49
Trackback 0 : 댓글을 오로지 페이스북으로만.

우리는 어떻게 한글을 사랑할 수 있을까?


뿌리깊은 나무 바람에 아니묄세

뿌리깊은 나무를 보았다. 1회 부터 빠짐없이 보았다. 세종대왕 그리고 한글에 대해서는 경기도 여주 태생인 나에게는 아주 익숙한 소재이다. 경기도 여주에는 세종대왕이 잠드신 영릉이 존재한다. 현재에 영릉에는 릉 뿐만 아니라 박물관이 존재하는지라, 여주 사람들은 한 두번씩은 아마도 가봤을 것이다. 
 
 

영릉 세종소헌왕후릉
주소 경기 여주군 능서면 왕대리 산83-1
설명 조선 제4대왕 세종대왕릉, 사적 제195호
상세보기




한글에 대한 나의 경험들. 


뿌리깊은 나무를 보면서 사실 세종대왕이라는 한글을 창제한 한 사람보다는 '한글' 자체에 대한 관심이 더 높아 졌다. 또한 현재 필자가 다니고 있는 회사 역시 한국어 검색을 기반으로 하는 검색엔진 업체이기 때문에 관심을 안 가질 수 없게 되었다. 내가 아는 한글은 초성 중성 종성으로 이루어져 있고, 자음과 모음으로 구성되어 있으며, 총 24자(원 28자)가 존재한다는 것 뿐이다. 물론 고등학교, 대학교때 국어 관련 수업을 들으면서 된소리 법칙 등에 대해서 배운적이 있다. 
 


[한글에 대한 우수성]
 

프로그래밍을 하면서 전 회사에서 언어 관련 프로젝트를 할 일이 있었다. 언어 학자라기 보다는 키패드를 만드는 발명가를 위한 소프트웨어를 개발해주는 프로젝트를 맡게 되었는데, 세계의 수많은 글자에 대한 입력 구현을 하는 작업이었다. 다국어 프로젝트였는데 중국어, 일본어를 제외한 한국어, 영어, 키릴어, 히브리어, 그리스어, 아랍어를 지원하는 키패드를 만드는 프로젝트였다. 해당 프로젝트를 하면서 느낀점은 한글이라는 글자에 대해서 좀더 소중함을 느끼게 되었다. 한글은 아랍어처럼 똑같은 여러 글자를 연달아 썼을 때 형태의 변형이 없으며, 또한 영어처럼 하나의 글자를 여러 형태로 발음하지도 않는다. 조합자이기 때문에 글자체를 만드는데 어려움은 있지만, 한글 자체는  뭔가 과학적이라는 생각이 들었다. 



한글에 대한 나의 생각.

 

네이버의 한글 사랑



뿌리깊은 나무를 통해서 한글에 대해서 다시 생각해 보게 되었다. 나에게 한글은 무엇일까? 그냥 한국안에서의 의사소통을 위한 글자? 이런 생각도 들었다. 너무 우리 한국사회가 미국에 대한, 서양에 대한 사대주의에 빠져서 영어를 더 한글보다 우월하다고 생각하고 있는건 아닌가 하는 생각이 들었다. 그래서 굳이 영어를 쓰지 않고 한글로 대체할 수 있음에도 불구하고 영어를 더 쓰는것은 아닌가 싶기도 하다. 
 

그런 과정에서, 최근에 지속적으로 진행되고 있는 네이버의 한글 관련 프로젝트를 보면서 대단하다는 생각이 들었다. 물론 그정도 규모가 되니까 그럴수 있다고 하지만, 나눔고딕이라는 글자체를 만들어 내고 그것을 단순히 배포하는 것이상으로 네이버 사이트에서 직접 사용자가 적용해 볼 수도 있고, 아름다운 한글 서식문서를 배포 하는 모습을 보면서 저런것이 바로 '한글을 사랑하는 자세'가 아닌가 하는 생각이 들었다. (심지어 코딩용 글꼴도 있다.)

[나눔고딕 찾아보기
]


그렇다면, 우리는 어떻게 한글을 사랑할 수 있을까?
 

영어의 사용은 불가피하다. 특히 정보기술(IT)에 있는 사람들은 더 그렇다. 사실 나는 업무중에 대부분을 영어를 쓴다. 말이 아닌 글자. 영문 기술문서를 찾아보고, 또는 영문으로 코딩을 한다. 그건 어쩔수 없다. 어떤이들이 말하는 한글의 축약현상 혹은 ㅇㅇ, ㅋㅋ 이런것을 한글의 파괴현상이라고 하는데 나는 이것이 한글의 위기라고 생각하지 않는다. 그것은 마치 영어의 ASAP를 쓰는것과 같다. 21세기의 또 다른 한글의 진화하는 모습인것이다.

ㅇㅇ은 그 자체만으로도 의미 "응. 알겠어." 라는 의미를 갖고 있으며, "ㅋㅋ" 라는것은 이제는 웃을때 쓰는 것이상으로 "ㅋ" 의 개수 만큼 자신의 신나는 감정 표현을 말한다. "...." 을 길게 쓰는 것은 단순한 말 줄임표가 아닌 나의 서운한 감정을 드러내기도 하는 것이라고 생각한다.  


뿌리깊은 나무에서 말한것과 같이 언어/문자란 역병과 같은 것이어서 한 사람이 쓰고 그것이 편하다고 생각되어 지면 빨리 퍼진다. 그리고  그런 현상에 날개를 달아주는 것이 지금 시대에는  인터넷이고 소셜 네트워크인 셈이다. 그렇기에 막을수 없고, 막는다고 막아지지 않는다. 


나는 이런 생각을 해보았다. 
어떻게 한글을 나 나름대로 사랑할수 있을까? 


나는 프로그래머다. 한글 자판은 이미 나와있고, 한글을 위한 워드프로세스 역시 나와있다. 그러면 나는 할수 있는 일이 없는 것일까? 그러던중 문득 생각이 들었다. 글자라는 것은 말(음성)과는 다르게, 형태가 있기 때문에 눈으로 보이고 많이 보여야 사람들도 많이 쓰게 된다고 생각하게 되었다. 지극히 당연한 것이다. 즉, 한글을 사랑한다면 많이 써야하고, 많이 모니터 혹은 공책 등에 표시가 되어야 한다. 


나는 내 나름대로의 나만의 한글을 사랑하는 방법을 정했다. 그것은 외래어 특히 영어를 영어 그대로 쓰지 않는 것이다. 생각해 보면 웃긴것 같다. 영어를 쓰는 나라에서 그 나라 책이나 그 나라 사람들이 쓰는 블로그, 뉴스, 기사에서 우리나라를 "한국" 이라고 쓰는가? 아니면 "KOREA" 라고 쓰는가? 그럼에도 불구하고 나는 너무 블로그에서 한글과 영어를 혼용해 왔었던 것 같다. 


사실 좀 부끄럽다. 한편으로는 너무 영어를 쓰면서 영어좀 안다. 이런 아는척 한것이 아닌가. 
 

그래서 나만의 한글을 사랑하는 방법으로 외국어를 외국어로 쓰는 것이 아니라, 한글의 외래어 표기법대로 쓰는 것으로 정하기로 하였다. 즉, Python 이라고 썼으면 파이썬 혹은 파이썬(python) 이런식으로 쓰는 것이다.  어려운 글자들도 많다. pydev 를 파이데브 이렇게 쓰는 것은 좀 어색하다. 하지만, 처음부터 익숙한 것은 어느 것도 없다. 자꾸 쓰다보면 늘게되고, 익숙하게 된다고 생각한다. 


각자가 할수 있는 한글 관련 프로젝트를 해 보는 것은 어떨까?
 


[산돌광수 커뮤니케이션 대표 : 석금호]


우린 각자가 다른 직업을 가지고 있을것이다. 어떤 사람은 디자이너, 어떤 사람은 프로그래머, 어떤 사람은 사무직 등등. 곰곰히 생각해 보면 각자의 능력을 가지고 한글을 사랑할수 있는 각자만의 방법이 있을 것이다. 어떤 사람은 폰트를 만들고, 어떤 사람은 한글관련 소스코드를 만들고, 어떤 사람은 한글 관련 서식을 만들고. 재밌을 것 같다. 1년 동안 한번 앞에서 말한 외래어 표기에 대한 수정 작업도 진행해 보고 나름대로 '한글사랑 프로젝트' 라는것도 해서, 2012년 10월 9일 한글날에 각자의 블로그를 통해서 발표해 보는것도 좋을 것같다. 


...그리고 국어 국문학자들에게 드리는 글. 

한글의탄생문자라는기적
카테고리 인문 > 언어학
지은이 노마 히데키 (돌베개, 2011년)
상세보기
 
최근에 한글에 대한 원리 그리고 역사와 구성에 대해서 알고자 서점을 찾았다. 그리고 한글의 원리, 한글 이라는 단어로 교보문고의 도서검색을 해 보니 "한글의 탄색 : 문자라는 기적" 이라는 책이 보였다. 이런책이 있다는 것이 감사하긴 하다만, 저자가 노다 히데키라는 일본인 이라는 점에서 솔직히 좀 많이 아쉽다. 국어국문학 뿐만아니라 인문학 자체가 실종이 된 상태이긴 하지만, 현재 남아 있는 학자라도 뿌리깊은 나무를 통해서 이렇게 세종대왕과 한글 자체에 대한 관심이 높아진 시점에서 일반인들도 쉽게 읽을수 있는 한글에 대한 책을 한권쯤 내놓은 것 역시 그들(국어국문학자)이 할수 있는 최소한의 한글 사랑이 아닐까 생각해 본다. 


저작자 표시 비영리 변경 금지
Projects/Sejong 2011/12/26 01:55
Trackback 0 : 댓글을 오로지 페이스북으로만.

[JAVA] HashTable 을 이용한 로컬캐쉬(LocalCache)

매일매일 개발하는 소스코드를 올리고 있습니다. 원래는 프로젝트가 끝나고 올리려고 했으나, 그러다 보니 까먹는 경우가 있어서 이렇게 매일매일 올리는 소스코드 입니다. 제가 쓴 소스코드의 문제 혹은 개선점이 있으면 언제든지 댓글 달아 주세요 

자바 프로그래머도 아니면서 자꾸 자바 소스코드를 내놓게 되는데 사실 환경만 구축되어 있으면, 이것만큼 쉽게 프로토타입핑을 쉽게 해 볼수 있는 언어도 드문것 같다. 오늘 소개한 코드는 일명 로컬캐쉬(LocalCache) 라는 것이다. 만든 취지는 원래 회사에서 캐쉬관련 모듈이 있는데, 캐쉬라는것은 한 마디로 미리 저장해 놓는 개념이라고 볼수 있다. 그래서 자바의 HastTable 을 이용해서 로컬캐쉬 즉, 프로그램 내에서 싱글턴의 형태로 존재하면서 무엇인가를 저장하고 있다가 요청하게 되면 반환해 주는 것이다. 여러가지로 활용될수 있는 여지가 있다고 생각되어 진다. 특정 API 관련된 결과를 다시 호출할 필요없이 일정기간 내에서는 로컬 캐쉬내에서 찾아서 보여준다면 빠르지 않을까?


import java.util.*;

public class LocalCache
{

    private Hashtable local_hashtable = new Hashtable();
    private static LocalCache shared_object = new LocalCache();
    private int limit_chche_entry = 10000;
    public Timer timer = new Timer();
    boolean isMutexOpen = true;

    private LocalCache()
    {
      // Do not use Constructor() because of Singleton instance
    }

    public static LocalCache getInstance()
    {
      return shared_object;
    }

    public void startTimer(int limit_mili_sec)
    {
      timer.schedule(new CleanCacheTimerTask(), limit_mili_sec);
    }

    public void stopTimer()
    {

      timer.cancel();

    }

    public void setLimitEntry(int limit_number)
    {
      limit_chche_entry = limit_number;
    }

    public int getLimitEntry()
    {
      return this.limit_chche_entry;
    }

    public boolean setCache(String key, Object value)
    {

      boolean is_added = false;
      for (;;)
      {
          if (isMutexOpen == false)
          {

            if (isExistKey(key) == true)
            {
                is_added = false;
                break;
            }
          }
          else
          {
            isMutexOpen = false;
            if (this.countCache() >= limit_chche_entry)
            {
                System.out.println("limit number : "
                      + this.limit_chche_entry);
                is_added = false;
            }
            else
            {
               
                  this.local_hashtable.put(key, value);
                  is_added = true;
               
                  
            }
            isMutexOpen = true;
                break;
          }
      }

      
      return is_added;

    }

    public Object getCache(String key)
    {
      return this.local_hashtable.get(key);

    }

    public boolean isExistKey(String key)
    {
      return this.local_hashtable.containsKey(key);

    }

    public void clearCache()
    {
      this.local_hashtable.clear();
    }

    public void delKeyInCache(String key)
    {
      if (this.local_hashtable.containsKey(key) == true)
      {
          this.local_hashtable.remove(key);
      }

    }

    public int countCache()
    {
      return this.local_hashtable.size();
    }

}

class CleanCacheTimerTask extends TimerTask
{
    public void run()
    {
      LocalCache cache = LocalCache.getInstance();
      cache.clearCache();

      cache.timer.cancel();

    }
}

 

위의 소스코드를 보시면 알겠지만, 단순하게 HashTable을 이용하고 있다. 그리고 몇가지 장치를 두었는데 :


1. 용량제한 장치 

- 사실 엄청 많은 데이터를 넣을수는 있지만, 메모리 부족 문제가 생길수 있다. 그리고 해쉬테이블 상 Java 의 Object 형을 인자로 받기 때문에 모든 형들이 다 들어갈수 있다. 원래 취지는 데이터 사이즈를 고려해서 특정 데이터 사이즈 이상은 넣지 않는 것으로 할려 했으나, C에서 처럼 sizeof() 함수가 없기 때문에 건수 자체(limit_chche_entry )를 지정하는 방식으로 되어 있다. 



2. 타이머 기능

- 타이머 기능은 당연히, 특정 시간 동안에만 캐쉬를 유지하는 기능이다. 너무 오랫동안 유지할 경우, 메모리 부족의 문제도 있기 때문에 시간을 둔것이다. 사용자가 설정한 시간이 지나면 저절로 해쉬테이블 내의 모든 데이터를 초기화 시킨다. 


3. 멀티스레드 기능
- 당연히 멀티스레드를 생각했었고, 처음부터 멀티유저 동시 접속시의 성능향상을 위해서 만든 것이다. 때문에 멀티스레드를 위한 다양한 장치를 했는데 우선 본 클래스의 인스턴스 생성은 아예 한번만 이루어지고, 해당 인스턴스를 빌려서 쓰게 만드는 방식을 사용했다. 사실은 getInstance() 함수에서 Null 인지를 체크하고 널인 경우에만 인스턴스를 생성해서 반환하는 방식을 사용했는데 멀티쓰레드의 보장 문제가 테스트 할때 발견이 되어서 급히 수정했다. 그리고 또 한가지는 바로 setCache() 함수시의 내부에서 선 진입스레드가 수행하고 후 진입 스레드는 계속 대기(waiting)하는 것이 아니라, 대기하면서 계속 해쉬테이블 안에 키가 있는지 확인하는 과정을 거치게 만들었다. 선진입한 스레드와 후 진입한 스레드가 동일한 데이터를 쓰려고 하면 문제가 발생하는것은 아니지만, 후 진입한 스레드의 입장에서는 시간낭비이기 떄문이다. 


사실 이 로컬캐쉬 코드와 쌍으로 이루어서 쓸수 있는것은 전에 포스팅에서 했던 MD5를 만드는 자바코드이다. 사실 해쉬테이블은 키-값, 키벨류 방식의 사전(Dictionary) 형태이기 때문에 하나의 데이터를 넣기 위해서는 고유한 키가 필요하다. 때문에 MD5 코드를 통해서 특정한 string 값을 입력하면 MD5의 형태로 문자열을 출력하고, 그 문자열을 해쉬테이블의 키 값으로 사용하는 것이다. MD5가 완벽하게 확실한 키 값을 추출해 준다고 말할수는 없겠지만, 테스트 결과 같은 문자열을 넣으면, 같은 MD5 키를 추출해 주었다.


좀더 좋은 의견이나 개선사항이 있으면, 무조건 댓글 달아 주시라.^^ 
 
저작자 표시 비영리 변경 금지
Technique/etc 2011/11/30 10:04
Trackback 0 : 댓글을 오로지 페이스북으로만.

[iOS] 자동 개월수 계산 코드

이번 한우찾기 2.0 에 들어간 코드인데, 텍스트 형태로 받은 날짜와 오늘의 날짜 사이의 간격을 계산해서 개월수를 구하는 코드입니다. 별 다른 어려운 코드가 없으니 보시면 바로 이해가 가능할것 같네요. 자 코드 나갑니다. 
 

                   //날짜 계산

                   NSDate *today = [NSDate date];

                   today= [today dateByAddingTimeInterval:+(9*3600)];

                  

                   NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];

                   [dateFormatter setDateFormat:@"yyyy-MM-dd"];

                  

 

                   NSDate *Fromday = [[NSDate alloc] init];

                   Fromday = [dateFormatter dateFromString:/*기준 날짜*/];

                                    

                   NSDateComponents *dateComp = [[NSCalendar currentCalendar]

                                                                                      components :NSDayCalendarUnit

                                                                                      fromDate : Fromday

                                                                                      toDate : today

                                                                                      options:0];

                  

                   int comp = [dateComp day];

                   int moc = comp/30;

          

                   NSString *dateString = [dm GetlblBirthDate];


저작자 표시 비영리 변경 금지
Technique/iOS Dev 2011/05/07 10:22
Trackback 0 : 댓글을 오로지 페이스북으로만.

한우찾기 v2.0 프로모션 동영상





저작자 표시 비영리 변경 금지
Projects/한우이력추적조회 2011/05/03 18:02
Trackback 1 : 댓글을 오로지 페이스북으로만.

[App] 한우찾기 v2.0 출시

장장 1개월의 개발기간. 그리고 약 일주일간의 심사과정을 지나서 지난 일요일(5/1)에 하국 앱스토어에 한우찾기 v2.0 이 정식 업데이트 되었습니다. 자, 그럼 무엇이 업데이트 되었는지 볼까요?


첫화면




1. 새로운 기능 

총 3가지 새로운 기능이 추가되었습니다. 

첫번째 새로운 기능은 축사물 등급판정소 조회 기능을 추가함으로써 기존의 한우를 키우시던 분들은 도축 후의 육질등급 뿐만 아니라 도체중과 육질등급을 알 수가 있으며, 그것을 통해서 도축한 소의 대략적인 가격을 알수 있게 되었습니다. 

축산물 품질 평가원 데이터






두번째 새로운 기능은 자동 개월수 계산 기능입니다. 이게 왜 필요해? 라고 반문하시는 분들이 많으실것 같은데 실제 소를 사러 가서는 해당 한우가 생후 몇개월이 됐는지 중요하다고 하더군요. 그리고 그런 부분에 대한 확인을 서류나 혹은 소의 이빨 성장을 보고 판단한다고 합니다. 서류로 확인할 경우, 머리아프게 개월수 계산하는 것이 불편하기때문에 신속성을 위해서 제공한 기능입니다. 

자동 개월수 계산





세번째 새로운 기능은 소 이동 정보와 구글맵 연동 기능입니다. 원래 한우는 이동할때마다(주인이 바뀐다 라는 의미), 전산등록을 해주는 것이 필수 입니다. 그리고 그러한 정보는 쇠고기 이력조회 홈페이지를 통해서 확인할 수가 있습니다. 그래서 이동정보의 주소지와 구글맵을 연동시켜 전산등록, 도축출하 등이 이루어진 장소를 대략적으로 보여주고 있습니다

대략적인 위치정보 제공




2. 새로운 디자인 

아, 디자인으로 욕 많이 먹었습니다. 여자친구의 '디자인좀 이쁘게 하지' 라는 말이 비수를 꽂았고, 존경하는 프로그래머 형님에 디자이너를 꼭 구하라는 트위터의 말씀을 듣고 버전 2.0 들어가면서 디자이너를 섭외 했으나, 무보수로는 쉽지가 않더군요. 아무튼, 그래도 몇 가지 부분에서 새로운 디자인을 도입 했습니다. 


 깔끔한 아이콘 
일단 아이콘을 기존의 아이콘이 너무 성의 없어 보인다고 해서, 조금 변화를 준 형태로 바꾸었고, Shine 기능을 빼서 좀더 깔끔한 맛을 더했습니다. 처음으로 포토샵 작업을 해봤습니다.^^ (기존아이콘 보기)

new Icon

 


첫 화면의 변화 
첫 화면이 가장 중요하다고 하는데, 사실 저의 무리한 디자인이 한우 찾기 1.0 디자인 패악의 원인이더군요. 그래서 좀더 다양한 앱을 찾아 본 결과 진입후 화면의 모습 안에 로고를 삽입하는것이 좋다는 결론을 내어 아래와 같이 첫 화면을 바꿨습니다. 

v2.0

v1.0


통일성 있는 바코드모드 아이콘
바코드 모드의 아이콘 역시 지난 버전에서는 제가 직접 제작했으나, 솔직히 맘에 들지 않더군요. 가장큰 문제는 통일성이 없다는 거였습니다. 그래서 통일성 있게 바꾸었습니다. 그리고 UIPageView을 활용해서 좀더 사용자의 Interaction 적인 부분을 추가했습니다. 이 부분은 네이버 앱에서 영감을 받았습니다. 

카메라모드

사진모드


 



매직넘버 Five
탭바 역시 Magic Number 5. 즉, 사람이 가장 편안하고, 안정감 있게 느낀다는 5단 탭으로 변경했습니다. 그리고 아이콘의 변화도 주었구요, 더불어서 용어 탭을 두어 좀더 다양한 정보 제공을 주었습니다. 

대세는 Magic Number 5




3. 그리고.. Episode

많은 분들이 성원해 주셔서 감사합니다. 사실 목장을 하시는 분들, 축산업에 종사하시는 분들을 위해서 앱을 만들고자 했던 취지 자체가 그래두 성공적이었던것 같아요. 매일매일 많은 분들은 아니지만 지속적으로 다운을 받으신다는게 아무래도 널리 쓰고 있다는 것이겠지요.

제가 어느 자소서에도 썻듯이, 프로그램은 사용자가 써야 제맛입니다. 즉, 본연의 가치가  쓰임 자체에 있는 것이죠. 쓰여지지 않는 프로그램을 한 대학원까지 해서 5년 정도 만들었던것 같아요. 슬펐고, 짜증났고. 그래서 쓰는 프로그램을 만들자는 취지에서 앱 개발을 시작했는데, 본업보다 더 짜릿하네요. 


 
SNS를 통해서 피드백을 받곤 하는데, 이 어플의 필요성에 대해서 의문을 가지시는 분도 있는 반면에 어떤 분은 새로운 앱을 제시하기도 하면서 유료로 만들면 사겠다고 하시는 분도 있었습니다.

의외로 오프라인 마케팅의 위력도 실감했습니다. 거래하시는 사료업체에 한번 소개를 했더니 갑자기 그 날 다운로드 횟수가 폭발적으로 증가하더군요. v2.0 이 나오면서 키노트로 영상을 제작하고, 프리미어로 음악과 합치는 작업도 해보고 정말 어렵지만 행복했던 작업이었던것 같습니다. 

한우찾기 어플에 성능향상 작업은 사실 좀더 할 예정이긴 합니다만, 메이저 급의 기능 추가와 함께 릴리즈 할까 생각합니다. 그 외의 버그나 혹은 문제에 대해서는 수시로 메일링 체크를 하고 있으니 알려주시면 감사하겠습니다. ^^

ps) 기술적인 질문 사항이 있으시면 언제든지 댓글 달아 주세요(소셜댓글) 
저작자 표시 비영리 변경 금지
Projects/한우이력추적조회 2011/05/03 17:47
Trackback 1 : 댓글을 오로지 페이스북으로만.

문득.. 그런생각이 들었다.





문득.. 그런 생각이 들었다.

버스정류장에 서서.
나는 불현듯. 당신과 함께 할수없다면.

나는 어떻게 될까?

짧은 순간이었지만, 드는 생각은

같은 서울 하늘 아래에서 살수가 없을것 같다.

처음 가봤던 압구정의 한까페.
화장을 하는 모습이 기억에 나는 한 박물관.
화나서 서로 말없이 걸었던 빨간모자네집.
사랑한다고 소리질렀던 스케이트 장.
샴페인을 처음 같이 마셨던 남산의 어느 놀이 좋은 바.

당신과 함꼐한 추억이 서린곳들이 너무 많아서.

문득.. 그런 생각이 든다.
당신이 보고 싶다고.

아직 나는 해보지 못한것이 많다.
내일은 남산을 가야겠다.


- 안 성현 -

저작자 표시 비영리 변경 금지
Culture/詩 2011/02/04 18:47
Trackback 0 : 댓글을 오로지 페이스북으로만.

[C#] 윈폼 컨트롤 박스 없이 마우스 드래그앤 드롭으로 이동.

        
원래 다른 분 블로그에 있었던 것인데, 퍼왔습니다. 출처를 표시해야 하는데, 프로젝트 코드에 넣은지 꽤 돼서 출처 찾기가 힘드네요. ㅠ 혹시 보시다가 본인이 쓴 글이라고 하시면 출처표시 해 드리겠습니다. 

일단 설명을 드리자면, 윈폼에서 최소화, 최대화, 닫기 및 상단의 텍스트 표시를 없애고 이미지만 나오게 윈폼을 개발하는 경우가 있지요. 사실 ControlBox 를 마우스로 드래그앤 드롭하면 움직이는데, 전체를 이미지로 덮어 버리는 경우에는 그런 부분을 만들어 줘야 합니다. 

public Point ptRect = new Point(0, 0);

private void panel_Keypad_MouseDown(object sender, MouseEventArgs e)
{
            ptRect.X = e.X;
            ptRect.Y = e.Y;
}

private void panel_Keypad_MouseMove(object sender, MouseEventArgs e)
{
            if (e.Button == MouseButtons.Left)
            {
                Point pt = new Point(this.Location.X + e.X - ptRect.X,this.Location.Y + e.Y - ptRect.Y);
                
                this.Location = pt;
            }
}


C++ 에서의 구현(2011.07.21 Update)

void CLoginDlg::OnLButtonDown(UINT nFlags, CPoint point)
{  
        PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y)); 
 
CDialogEx::OnLButtonDown(nFlags, point);
}


다이얼로그의 OnLButtonDoown 에서 위의 PostMessage 부분 추가해 주면 됨. 생각보다 쉽게 구현됨. 

저작자 표시 비영리 변경 금지
Technique/C/C++/C# 2010/11/18 11:28
Trackback 0 : 댓글을 오로지 페이스북으로만.

[Windows Phone7] mini Browser Sample 분석

 

Windows Phone 7 코드 샘플 4가지를 분석해 보는 시간을 갖도록 하겠습니다. 총 4가지의 샘플을 분석하는 이유는 보통 C#에서 쓰던 클래스 라이브러리가 있지만, Windows Phone7으로 오면서 달라진 점도 있을수 있고, 또 위치 정보 서비스 또는 가속도 같은 경우에는 에뮬레이터 설정을 바꿔줘야 하는 경우가 있기 때문에 분석의 필요성을 느꼈습니다. 

mini Browser 
 
먼저 미니 브라우저에 대한 샘플 코드를 다운 받으시고, 압축을 푸세요. 물론, 지금 이 글을 보시는 분들은 Windows Phone 7 개발 환경이 구축되어 있어야 합니다. sln파일을 더블클릭 하시면, 다음과 같은 화면이 나올것입니다. 

일단 어떻게 동작하는지 먼저 구경을 해보자구요. 금강산도 식후경이라는 말이 있듯이 분석을 하기전에 동작하는 모습을 봐야 감이 잡히겠죠^^



동작 시켜보면 알겠지만, 그냥 브라우저 입니다. 위의 창에 웹 사이트 주소를 입력하고 GO 버튼을 누르면 해당웹사이트로 이동하는 프로그램입니다. 사실 별거 없죠. 그럼 파헤쳐 볼까요?


User Interface
  
그럼 먼저 UI를 파헤쳐 보겠습니다. 솔루션 탐색기에서 MainPage.xaml 을 누르시면 위와 같은 UI가 나오게 됩니다. 기존의 Winform 어플리케이션과 달리 Windows Phone 7에서는 xaml로 UI를 개발하죠(물론 드래그앤 드롭으로 컨트롤을 배치할 수 있습니다.) App.xaml은 아니니까 누르지마시구요. 




창를 보게되면 왼쪽에는 UI가, 오른쪽에는 xaml 코드를 보실수가 있는데, UI와 xaml 코드가 서로 호환이 된다고 보시면 됩니다. 즉, UI의 어떤 속성을 바꾸면 xaml 코드에서서 어떤 부분이 바뀌게 되는것이지요. 

UI를 뜯어보면 크게 5가지가 보입니다. 작은 타이틀, 큰 타이틀, 주소창, GO 버튼 그리고 실제 웹페이지가 표시되는 부분입니다. 비주얼 스튜디오의 오른쪽을 보시면, Document Outline 이라는 메뉴가 보일것입니다. Document Outline을 누르면 현재 UI의 전체적인 구조를 보실수가 있습니다. 크게 하나의 Grid 컨트롤(LayoutRoot)안에 두개의 Grid, TitleGrid 와 ContentGrid 가 있습니다. TitleGrid 안에는 두개의 TextBlock이 있습니다. 이 두개의 TextBlock 을 이용해서 "My First Application" 이라는 것과 "Mini Browser"라는 것을 표시해 주고 있는것이지요. 그럼 ContentGrid 안에는 무엇이 있는지 볼까요?



ContentGrid 안에는 TextBox 와 Button 그리고 WebBrowser 컨트롤이 있습니다. 즉, 우리가 UI 화면만으로 봤을때는 그냥 다 하나의 바탕안에 있는것 처럼 보이지만 실제로는 Grid로 나누어서 관리를 하고 있고 이러한 것을 지원해 주기 위해서 Document Outline 이라는것이 존재하는 것 입니다. 

기존의 윈모바일의 윈폼 Application을 개발할때에는 사실 이런 부분이 많이 부족했었습니다. 하나의 Panel안에 여러 컨트롤들을 넣고 페이지 별로 관리를해도 사실 시각적으로 포함관계를 알수 없으면 개발할때 답답할 경우가 많았는데 이제는 그럴 염려는 없을것 같네요. 

ContentGrid를  살펴보면 3가지 컨트롤로 이루어져 있는데, 왜 TextBox와 Button이 존재하는 것일까요?

사실 .NET 에서 제공하는 Web Browser 컨트롤은 웹 페이지를 보여주는 역할만 하기 실제 우리가 익스플로러나 기타의 웹 브라우저 처럼 URL을 입력하는 창은 없습니다. 때문에 TextBox에 URL을 입력하고 Button을 누르면 해당 TextBox에 입력한 주소의 웹페이지를 WebBrowser 컨트롤에 보여주게 되는것이지요. 

그럼 코드를 살펴 볼까요?


Code 
  
UI 를 MainPage.xaml 을 보았기 때문에 코드도 MainPage.xaml.cs 를 보시면 됩니다. 보시면 다음과 같이 되어 있습니다. 


 public MainPage()
 {
    InitializeComponent();
    SupportedOrientations = SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape;
 }

 
우선 위의 코드가 생성자를 나타낸 다는 것은 다 아실테고, InitializeComponent() 함수는 윈폼 Application을 만들때 부터 자동으로 생기는 함수로 UI에 대한 초기화 작업이 되어 있는 부분입니다. 지금 보실 필요는 없고.

 SupportedPageOrientation.Portrait | SupportedPageOrientation.Landscape

 SupportedPageOrientation.Portrait

다음 코드를 보시면, SupportedOrientations 이라는 enum 형식의 것이 있는데, 이것은 현재 개발하는 어플에서 제공하는 Orientations (방향)을 지정할 수가 있습니다. 즉, 위의 코드에서는 Portrait (세로) 와 Landscape(가로) 모드를 다 지원한다는 것입니다. 실제로 에뮬레이터에 올려보시면, 세로에서 가로로 돌렸을때 "Mini Browser"라는 글씨가 제대로 보이지만, Landscape 를 빼게되면 돌려도 글자가 누운 상태로 보이게 됩니다. 개발하는 어플리케이션에 따라서 그런 부분을 고려해주어야 겠지요.


private void button1_Click(object sender, RoutedEventArgs e)
{
            string site;
            site = textBox1.Text;
            webBrowser1.Navigate(new Uri(site, UriKind.Absolute));
}


다음은 버튼 처리에 관한 코드입니다. 보시는것 처럼 아주 간단한데요 TextBox 에서 Text 를 받아와서 웹페이지를 보여주는 부분입니다. WebBrowser 객체에서 해당 주소의 웹페이지를 호출하는 함수는 Navigate 입니다. Navigate 함수는 파라미터로 Uri 를 받고 있기 때문에 다음과 같이 넣어 준것입니다. 

Uri의 생성자를 보면 다양한 형식으로 오버로드 되어 있는것을 볼수 있는데요. 그 중에서 여기서는

Uri(String, UriKind)

라는 것을 사용합니다. String 에는 웹 페이지 주소가 들어가게 되는데, UriKind 는 무엇일까요?

UriKind 라고 하는 것은 Uri의 종류를 정의한다고 나와있습니다. (Defines the kinds of Uris) 즉, 현재 쓰려고하는 Uri 가 절대 주소(example: http://www.contoso.com/index.html)인지 상대주소(example: /index.html) 인지를 나타내는것입니다. UriKind 는 enum 형식이고 3가지의 값을 가지고 있습니다. 


-  RelativeOrAbsolute  
-  Absolute  
-  Relative 

RelativeOrAbsolute 는 절대 주소인지 상대주소인지 애매할때 설정해 두는 것이라고 합니다. 사용자가 어떤 주소를 쓸지 모를때에 설정해 두면 좋을것 같네요


정리 

첫번째 샘플 코드 분석이었는데, 미니 브라우저는 생각보다 쉽게 구현할 수 있게 되어 있었습니다. 사실 기존의 .Net Compact Framework 나 윈 모바일에서도 이 부분은 webBrowser 컨트롤을 통해서 쉽게 구현이 가능한 부분이었습니다. 

하지만, Document Outline 이라던지, SupportedOrientations 같은 부분을 보면서, 기존의 윈 모바일보다 좀더 쉽게 구현할 수 있게 제공하는것 같습니다. MS는 개발자에게는 친절하다는 생각이 들었습니다. 


저작자 표시 비영리 변경 금지
Mobile 2010/03/19 10:23
Trackback 1 : 댓글을 오로지 페이스북으로만.

[Windows Phone 7] 윈도우 폰 7 개발 Getting Started




위의 링크에 들어가시면, 윈도우 폰 7 개발에 대한 설명이 자세히 나와 있습니다. 아래와 같은 화면이 뜨게 되는데요. 하나하나 살펴 보도록 하겠습니다.



View the Demo





Download the Developer Tools
개발 툴을 다운 받을수 있는 링크입니다.



위의 글을 가시면 Windows Phone Developer Tool CTP 에 대해서 좀더 자세히 설명되어 있는 것을 보실수 있을 것입니다. 참고로, Windows XP에서는 설치 할수 없음을 미리 알려 드립니다.




Documentation




Documenation은 역시 MSDN을 이용하고 있습니다. Windows Phone 전반적인 부분에 대해서 MSDN에서도 섹션을 별도로 두어 설명을 해 주고 있습니다. 가보시면 알겠지만, 기본적인 개발 환경 구성등의 처음 개발 할수 있는 절차에서 부터 클래스 라이브러리 뿐만 아니라 XNA 게임 개발이나, 실버라이트 어플리케이션 개발에 대해서도 나와 있습니다. 차차 내용이 보충될 것 같습니다.



Developer Guides
개발자 가이드에서는 3가지 PDF 문서를 제공해 주고 있습니다.

Application Platform Overview for Windows Phone
Windows Phone UI Design and Interaction Guide
Designing Web Sites for Phone Browse


코드 샘플에서는 현재까지는 총 4가지 코드샘플에 대해서 제공해주고 있습니다.

mini Browser Sample : 작은 웹 브라우저에 대한 샘플

Application Bar Sample : Application Bar 에 대한 샘플

Location  Service Sample : 위치정보 서비스에 대한 샘플

Accelerometer Sample : 가속도 센서에 대한 샘플


이렇게 4가지를 제공해 주고 있습니다. 사실 이 4가지가 모바일 기기에서 가장 핵심이 되는 부분이기도 하고 처음 개발자가 접근하기 막막한 부분이라서 MS 측에서도 우선적으로 올려주는 것 같습니다. 차차 많은 샘플이 올라올것으로 예상 됩니다.

샘플코드에 대한 분석은 차후의 포스팅을 통해서 진행 하도록 하겠습니다.


저작자 표시 비영리 변경 금지
Mobile 2010/03/18 09:40
Trackback 0 : 댓글을 오로지 페이스북으로만.