'umc'에 해당되는 글 168건

  1. 2015.02.25 [MonoDevelop] v5.7.2.2 한글 버전 배포 공지
  2. 2013.09.11 [Objective-C] 아름다움을 추구하는 오브젝티브-C 언어 1/ 2- 언어적 특성
  3. 2013.08.15 SharePoint 데이터베이스로 부터 모든 문서를 백업 및 추출하기 (2)
  4. 2013.08.05 [MonoDevelop] MonoDevelop 한글 버전 Github 병합 완료 (8)
  5. 2013.07.25 [MonoDevelop] MonoDevelop 통합 개발 도구를 한글화 진행 중입니다. (7)
  6. 2013.07.22 [JavaScript] JS-Lambda 자바스크립트 라이브러리를 공개합니다.
  7. 2013.07.17 [VS2013] VSGesture for Visual Studio 2013 Preview 배포 완료 (1)
  8. 2013.07.08 [퀴즈] 프로그래머를 위한 문제 #3 - 미로 찾기
  9. 2013.07.05 [퀴즈] 프로그래머를 위한 문제 #2 - 스택 프레임(Stack Frame) (1)
  10. 2013.07.02 [퀴즈] 프로그래머를 위한 문제 #1 - 1부터 8만까지 8의 개수 (9)
  11. 2013.07.01 [Javascript] jQuery 1.7.1 버그 패치를 공유합니다.
  12. 2013.06.20 [Google] 구글에서 활동한 내 모든 정보 백업 받자
  13. 2013.06.03 [Javascript] 자바스크립트(Javascript) 개발 팁과 가이드 (Tips & Guide) (6)
  14. 2013.05.31 [ALM] 13. 불완전한 통합, 팀 파운데이션 서버(Team Foundation Server)
  15. 2013.05.24 Umc Core IoC 통합 컨테이너 #1
  16. 2013.05.20 memcached, 분산 캐시를 이용하여 분산 Session 성능 향상 (1/2)
  17. 2013.03.11 [Qt] Qt 5.0의 webkitwidgets 사용 (3)
  18. 2013.01.24 [팁] 우분투(Ubuntu) 12.10 설치 중 창이 잘림 현상
  19. 2013.01.17 [Eclipse] STS 설치 실패 오류 유형 및 GEF(Graphical Editing Framework)
  20. 2013.01.17 [Java] Java 8 의 Lambda(람다) 표현식에 대한 고찰 (1)
  21. 2013.01.15 [Eclipse] Eclipse 에서 MinGW GCC 컴파일러로 C++11 사용하기
  22. 2013.01.15 [Eclipse] Eclipse Visual C++을 MinGW GCC 프로젝트로 변환하기
  23. 2012.10.30 윈도우 8, 반토막짜리 WinRT와 WinRT SDK (1)
  24. 2012.09.11 Windows 8 스타일 앱 개발에 대한 고찰
  25. 2012.08.09 윈도우 8, 뜨거운 감자 [2/2]-혁신은 언제나 리스크를 안고 간다 (4)
  26. 2012.08.09 윈도우 8, 뜨거운 감자 [1/2]-무엇이 사용자를 화나게 하는가? (4)
  27. 2012.08.02 MS OFFICE 2013, 그리고 구글은 당신이 지난 여름에 한 일을 알고 있다! (1)
  28. 2012.08.02 개발자도 알아야 할 응용 프로그램 모델링 7/7 - 결론 및 저자 소개 (1)
  29. 2012.08.02 개발자도 알아야 할 응용 프로그램 모델링 6/7 - 모델링 확장 (SDK)
  30. 2012.08.02 개발자도 알아야 할 응용 프로그램 모델링 5/7 - Visualization & Features Pack

- MonoDevelop v5.7.2.2 한글 버전 빌드 업데이트

2013년부터 꾸준히 진행해 오던 MonoDevelop v5.7.2.2 한글 버전의 새로운 빌드를 업데이트 했습니다.

MonoDevelop v5.7.2.2 한글 버전은 다음의 링크에서 다운로드 받을 수 있습니다.


- 왜 MonoDevelop을 써야하나?

외국 Xamarin 기업에서 Mono 오픈소스 재단을 인수하면서 Mono 가 폭풍성장을 하고 있습니다.

이제 따른 부작용이 Xamarin이 Mono를 통해 수익을 얻으려 하는 것이죠. 물론 돈은 벌어야 하니까요. 따라서 Xamarin Studio 를 사용하고 Xamarin.*.dll 라이브러리에도 GPL 라이선스 제한을 받게 됩니다.

이에 반해 Mono와 MonoDevelop은 MIT/X11 & LGPL2 라이선스이므로 적절한 전략을 통해 크로스 플랫폼 데스크탑/모바일 개발이 가능할 수 있습니다. Unity 게임 개발에도 MonoDevelop 이죠. ^^

더 궁금하신 점이 있으시면 언제든지 이메일 주시기 바랍니다. (댓글이나 방명록 잘 확인을 안해요;;)

Posted by 땡초 POWERUMC

댓글을 달아 주세요

아름답고 자연스러운 오브젝티브-C

필자가 오브젝티브-C(Objective-C)를 접한 것은 올해 초, 갑갑한 문법적인 표현(Syntax)을 보니 코드를 보기가 싫어졌었다. 하지만 많은 iOS 개발자가 생겨나고 맥킨토시(Macintosh)를 쓰면서 자연스럽게 맥용 응용 프로그램에 관심이 생기기 시작했다. 처음에는 리눅스와 대부분의 운영체제를 지원하는 Qt(큐티) 프레임워크를 봐오다가, 코코아(Cocoa) 를 알게 되면서 맥킨토시에 가장 아름다운 UI 프레임워크인 것을 느끼게 되었다고 할까.

오브젝티브-C는 매우 깊은 역사가 있다. 이 역사에 대해서는 다음의 위키피디아(Wikipedia) 를 참고하기 바란다. 필자도 이 언어에 대한 깊은 역사를 이렇다 할 만큼 자신 있게 설명해 주기 힘들 것 같다.

.. 생략 .. [1]
오브젝티브-C는 스텝스톤(Stepstone)이라는 회사에서 일하고 있던 브래드 콕스(Brad Cox)와 톰 러브(Tom Love)라는 두 연구원이 만들었다. 역시 1980년대 초의 일이다. 이 두 사람은 1981년 ITT의 프로그래밍 기술 센터(Programming Technology Center)에서 일하던 시절 스몰토크를 처음 접했다. 콕스는 소프트웨어 설계와 프로그래밍에 있어서 재사용성의 문제에 흥미를 느끼게 되었고, 스몰토크같은 프로그래밍 언어가 ITT 시스템 개발자들이 개발을 진행할 강력한 환경을 만드는 데 필요불가결한 요소임을 깨닫게 되었다. 콕스는 C 컴파일러를 고쳐 스몰토크의 기능 일부를 추가하기 시작했고, 곧 그 스스로 OOPC라고 불렀던 C의 객체지향 버전을 내놓게 되었다. 한편 러브는 1982년에 Schlumberger Research에 채용되었고, Smalltalk-80의 최초 상업적 버전을 써 볼 기회를 가지게 되었다. Smalltalk-80은 이후 그들이 낳은 정신적 자식의 성장에 큰 영향을 끼쳤다.
.. 생략 ..

필자가 오브젝티브-C를 접하면서 ‘빙고!’를 외쳤다. 현대적인 언어의 대부분이 C언어, 그리고 바로 이 오브젝티브-C 언어의 영감을 받았다고 해도 무리는 아니다. (단, 현대적인 언어의 정의는 스스로 정의를 내리기 바란다.)

그렇다면 왜 오브젝티브-C 언어가 아름다운지 보자.

아름다움을 만들어 준 메시지 기반 언어

오브젝티브-C의 가장 기초적인 문법을 일반적인 객체 지향 언어의 문법과 비교해 보자.

// 일반적인 객체지향 언어들의 표현
void* obj = data->get_data(); // 또는
void* obj = data.get_data(); // 또는
Object obj = data.get_data();

// 오브젝티브-C 언어
NSObject* obj = [data get_data];

위의 일반적인 객체지향 언어와 오브젝티브-C 언어는 표현하는 방법에 있어 다른 점이 보인다. 자, 무엇이 다른지 한번 살펴보자.

  1. 문법 표현 방법 : 가장 차이가 나는 점은 식의 표현을 대괄호([ ])로 묶여 있다. (메서드 호출 시)
  2. 메서드 호출 방법 : 포인터(->) 또는 참조(.)를 통해 호출하지 않고 공백(a space)으로 메서드를 가리켜 호출한다.

위 코드가 컴파일 된다면 더욱 명확하게 차이점을 볼 수 있다.

일반적인 객체지향 언어의 경우 컴파일 된 어셈블리(기계어) 코드는 메서드가 메모리 상에 상주하고 있는 주소를 통해 직접 메모리를 엑세스하여 메서드를 실행한다.
오브젝티브-C의 경우 바로 이것이 오브젝티브-C 언어의 특징인 메시지를 통해 메서드를 호출하는 방법이다. data 객체는 get_data() 메서드를 직접 호출하지 않고 다른 대리자(위임)를 통해 메서드를 실행한다.

그렇다면 오브젝티브-C는 대리자를 통해 메서드의 실행을 위임함으로서 장점은 뭘까?

  1. NullPoint 예외(오브젝티브-C의 nil 또는 NULL)나 기타 치명적인 오류를 언어적인 레벨에서 차단한다.
  2. 관리언어(Managed Languages)인 자바, C# 등에서 즐겨 쓰는 Code Interception 등의 기법과 유사한 것들을 쉽게 확장할 수 있는 포인트를 제공한다.
  3. LLVM과 같은 가상 머신(Virtual Machine) 매커니즘을 손쉽게 적용할 수 있다. (clang)
딱히 바로 생각나는 것은 몇 안되지만, 더 많은 장점이 있음은 분명하다. 그리고 오브젝티브-C의 메시지 기반으로 작동하는 언어적인 특성을 분석해보자

오브젝티브-C 메시지 기반 메서드 호출

1. objc_msgSend 함수의 메커니즘

오브젝티브-C는 objc_msgSend() 함수를 이용하여 메시지를 보낸다. 이것은 함수만 해당되는 사항은 아니다. 위에서 살펴본 것과 같이 식의 표현을 대괄호([ ... ]) 안에 코드로 표현하는데 이 대괄호 안에 들어가는 모든 객체건 뭐건 간에 메시지를 통해 값을 가져오거나 메서드를 호출하게 된다.

아래 보이는 어셈블리 코드는 필자가 오브젝티브-C로 작성한 맥용 데스크탑 응용 프로그램 중 일부를 어셈블리 레벨에서 디버깅 하는 스크린샷이다. 다음에 사용된 코드의 일부는 다음과 같다.

[self.sidebar setTarget:self];

sidebar는 인스턴스화 된 객체(Object)이다. 오브젝티브-C는 메서드 호출에서만 메시지를 보내는 것이 아니라는 것이다. 그리고 objc_retainAutoreleasedReturnValue() 함수는 매우 긴 이름이지만, 맨 앞 글자의 retain만 주목해서 보면 된다. sidebar 인스턴스는 현재 컨텍스트(Context)에서 참조하므로 참조 카운터(References Count)를 1 증가 시킨다.


2. objc_msgSend 함수 내부에서 전달받은 메시지

아래의 스크린샷은 objc_msgSend() 함수의 내부에서 RIP 레지스터가 가리키는 메모리 주소의 HEX 이다. '73 69 64 65 62 61 72 00'(sidebar) 문자열은 objc_msgSend() 함수에 의해 RTTI(Run-time Type Information) 정보로 객체를 가져오기 위한 메시지라고 보면 된다. lldb의 're r' 명령을 통해 레지스터의 값들을 확인할 수 있다.

얼핏 보아도 아래의 스크린샷의 메모리 공간은 인스턴스 객체의 메시지와 메서드의 메시지들을 몰아서 외부에서 참조할 수 있도록 나열한 것임을 알 수 있다.


3. objc_msgSend() 메서드의 시그너처가 선언된 곳에서 objc_msgSend 호출

lldb 디버거를 통해 ni 명령으로 objc_msgSend() 함수에 진입하면 메시지 전달 함수가 메모리 상에 상주해 있는 곳으로 이동 시킨다.


4. 컨텍스트(Context)에서 전달된 메시지를 순회하여 검색/실행

전달되는 메시지를 통해 인스턴스의 메타데이터를 사용하여 실제로 객체를 가져오게 된다. 아래의 네모난 상자의 명령들이 바로 객체를 찾아오기 위한 루프(Loop)이다. 


5. 메시지에 의해 처리된 객체는 일부 캐싱하여 성능 향상을 꾀함

재미있는 점은 매번 메시지의 정보를 순회하면서 찾지 않고, 한번 찾은 정보는 별도로 캐싱 하고 있는 공간에서 검색하게 된다.


지금까지는 sidebar 인스턴스를 가져오기 위한 과정이었다. 이제 이 인스턴스 객체의 메서드를 호출하는 과정인데, objc_sendMsg()를 통해 메시지를 전달하여 찾은 메서드를 실행하게 된다.



Posted by 땡초 POWERUMC

댓글을 달아 주세요

SharePoint 데이터베이스로 부터 모든 문서를 백업 및 추출하기

개요

필자는 SharePoint 서버 제품을 이용해서 문서를 관리해 왔다. SharePoint를 이용하면 수 천개의 문서를 종류별로 분류하고 데이터베이스화할 수 있다. 문서의 종류와 문서의 내용도 인덱싱(indexing)되므로 문서 내용과 다양한 메타 데이터로 문서를 검색할 수 있다는 점 때문에 많은 문서를 쉽게 관리하고 검색할 수 있다는 장점이 있다.

SharePoint의 장점을 나열하지면 많겠지만, 모바일 트랜드 시대에서는 에버노트가 최고이지 쉽다. 필자의 에버노트와 DropBox는 땡전 한푼 안들이고 프리미엄 서비스를 받고 있는데, 필자가 문서를 사용하고 관리하는 패턴에선 SharePoint 보다는 에버노트DropBox 조합이 더 접근성이 좋고 사용하기도 편하다. 데스크탑은 물론이고 브라우저, 다양한 모바일 기기에서 에버노트 클리핑과 DropBox 동기화 등을 지원하기 때문이다.

그래서 이번에 필자가 가지고 있는 수 천개의 모든 문서를 이전하고자 SharePoint의 모든 파일을 추출해야 했다. 여기에서 여러 Site Collections/Sites/Doc Libs의 각각의 문서를 한 번에 추출하는 작업을 진행했다.

1. WSS_Content 데이터베이스 연결

원하는 툴을 이용해서 SharePoint가 사용하는 데이터베이스에 연결한다. SharePoint에 저장된 문서가 많을 수록 데이터베이스에 연결해야 하는 시간이 늘어난다. 그러므로 Timeout이 발생하지 않도록 주의해야 한다. 필자는 여기에서 SSMS(Sql Server Management Studio) 2012 버전을 사용했다.

2. 파일 추출하기

2.1. 데이터베이스 구성 변경 쿼리 실행

sp_configure 'show advanced options', 1;  
GO

RECONFIGURE;  
GO

sp_configure 'Ole Automation Procedures', 1;  
GO

RECONFIGURE;  
GO

2.2. 데이터베이스 추출 쿼리 실행

아래의 쿼리는 이 사이트의 링크[1]를 참고하였으나, 일부 오류가 발생하여 필자가 수정한 부분이 있으니 이점 참고하기 바란다.

그리고 SharePoint에 저장되는 파일들은 다양한 타입이 존재한다. 가령, 메타데이터의 Binary 파일, _private 폴더, *.aspx, 시스템에 필요한 파일 등 필자가 저장한 문서와 상관 없는 찌꺼기 들도 함께 저장이 된다.

파일의 다양한 플래그 값은 MSDN의 Document Store Type, Doc Flags 문서[2]를 참고 하면 된다.


  
[그림1] WSS_Content 데이터베이스의 모든 문서를 파일 시스템으로 추출한 결과 화면


USE WSS_CONTENT;  

DECLARE @PATH_PREFIX  NVARCHAR(1024);  
SET @PATH_PREFIX = 'C:\BACKUP\';  -- 이곳에 백업할 경로를 입력, 반드시 뒤에 '\' 문자 추가하셈'


--DECLARING THE CURSOR, THIS IS THE ITEMS YOU WANT TO RUN THE EXTRACTING ON  
DECLARE CURSOR_Images CURSOR FOR (SELECT Id FROM [dbo].[AllDocs])  

--DECLARE THE TYPE OF THE COLUMN YOU SELECTED ABOVE  
DECLARE @ImageID uniqueidentifier;  

--START THE CURSOR AND RUN THROUGH ALL THE ITEMS IN CURSOR_Images  
OPEN CURSOR_Images  
FETCH NEXT FROM CURSOR_Images INTO @ImageID  
WHILE (@@FETCH_STATUS <> -1)  
BEGIN  
  --DECLARE THE VARIABLE THAT WILL KEEP THE BINARY DATA  
  DECLARE @ImageData varbinary(MAX);  
  --SELECT THE BINARY DATA AND SET IT TO @ImageData.  THE BINARY DATA FOR ALLDOCS ARE LOCATED IN ALLDOCSTREAMS  
  --AND THE ID IS THE SAME AS IN ALLDOCS  
  SELECT @ImageData = (SELECT TOP 1 CONVERT(varbinary(MAX), Content, 1) FROM [dbo].[AllDocStreams] WHERE Id = @ImageID ORDER BY InternalVersion ASC);

  --GET THE LOCATION OF THE DIRECTORY THE FILES WAS SAVED IN AND CHANGE REPLACE THE / WITH \ TO BE USED IN FILESYSTEM  
  DECLARE @DIRPATH NVARCHAR(MAX);  
  SET @DIRPATH = REPLACE((SELECT  DirName FROM [dbo].[AllDocs]  WHERE Id = @ImageID),'/','\');

  --SET THE PATH  
  DECLARE @Path nvarchar(1024);  
  --SELECT @Path = 'C:\Export\' + @DIRPATH + '\';  
  SELECT @Path = @PATH_PREFIX + @DIRPATH + '\';
-- '\

  --CREATE THE DIRECTORIES  
  EXEC master.dbo.xp_create_subdir @Path;

  --GET THE FILE NAME OF THE FILE FROM LEAFNAME  
  DECLARE @Filename NVARCHAR(1024);  
  DECLARE @DocFlags INT;  
  DECLARE @Type     TINYINT;  
  SELECT @Filename = (SELECT LeafName FROM [dbo].[AllDocs] WHERE id = @ImageID);  
  SELECT @DocFlags = (SELECT DocFlags FROM [dbo].[AllDocs] WHERE id = @ImageID);  
  SELECT @Type     = (SELECT [Type]    FROM [dbo].[AllDocs] WHERE id = @ImageID);

  -- 폴더를 0바이트 파일로 생성하므로 파일이 아닌 경우 파일 저장 루틴 진입 금지  
  IF (@Type = 1 AND @DocFlags = 0) OR (@DocFlags & 0x100) <> 0x100 BEGIN  
CONTINUE;  
  END   
  ELSE BEGIN

  --SET THE FULL PATH FOR WHERE THE FILES WILL BE STORED  
  DECLARE @FullPathToOutputFile NVARCHAR(2048);  
  SELECT @FullPathToOutputFile = @Path + '\' + @Filename;

  --SAVE THE FILE TO THE FILE SYSTEM  -'
  DECLARE @ObjectToken INT  
  EXEC sp_OACreate 'ADODB.Stream', @ObjectToken OUTPUT;  
  EXEC sp_OASetProperty @ObjectToken, 'TYPE', 1;  
  EXEC sp_OAMethod @ObjectToken, 'OPEN';  
  EXEC sp_OAMethod @ObjectToken, 'WRITE', NULL, @ImageData;  
  EXEC sp_OAMethod @ObjectToken, 'SaveToFile', NULL, @FullPathToOutputFile, 2;  
  EXEC sp_OAMethod @ObjectToken, 'Close';  
  EXEC sp_OADestroy @ObjectToken;

  END

  --LOOP TO THE NEXT ENTRY IN THE CURSOR  
  FETCH NEXT FROM CURSOR_Images INTO @ImageID  
END  
CLOSE CURSOR_Images  
DEALLOCATE CURSOR_Images  

2.3. 참고 사항

위의 쿼리는 다양한 메타데이터와 시스템 파일(*.aspx, _private 등..)을 모두 저장한다. 이런 쓰레기 데이터를 파일로 저장하지 않길 원한다면 아래의 쿼리를 이용해서 조건절을 추가해 주면 된다.

각각의 플래그 값의 의미는 Document Store Type 문서를 참고하면 된다. 그러면 여러분이 원하는 데이터만 파일 시스템으로 추출하여 저장하도록 커스터마이징이 될 것이다.

SELECT LeafName, DocFlags  
  FROM [dbo].[AllDocs]  
 WHERE (DocFlags & 0x100) = 0x100
   AND (DocFlags & 0xFFFF0000) <> 0xFFFF0000
   AND (DocFlags & 0x80) <> 0x80
   AND (DocFlags & 0x10) <> 0x10
   AND (DocFlags & 0x8) <> 0x8  

결론

만약 SharePoint에 저장되었던 많은 파일 또는 데이터를 전혀 다른 솔루션으로 이전하고 싶은 경우가 있다. SharePoint는 Microsft SQL Server 데이터베이스에 바이너리를 저장하는데 파일 시스템을 단일 데이터베이스에 저장한다는 것이 좀 아이러니 한 구조이다.

많은 기업내 담당자들의 SharePoint에 대한 피드백을 물어보면 빠지지 않는 것은 ‘느리다’ 라는 것인데, 기하급수적으로 늘어나는 데이터베이스 용량과 웹 응용 프로그램의 SPSites/DocLibs 등이 생성되면서 시간이 지날 수록 점점 느려지는 것은 어쩔 수 없는 구조인 듯 하다. 더불어 SharePoint는 과거의 아키텍처가 현재까지도 트랜드의 변화에 대응되지 못하고 전반적으로 과거와 동일한 아키텍처에 새로운 기능만 계속 붙여나가다 보니 솔루션 자체의 구조적인 면에서 악순환이 되풀이 되는 형세이다.

하지만, 이 아티클을 통해 SharePoint 데이터베이스에서 직접 파일을 추출하여 파일 시스템으로 저장할 수 있다. 이 방법을 통해 추출된 다량의 파일을 다른 솔루션으로 옮기거나 업로드하면 끝이다.


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 억사마 2014.02.03 18:00 신고 Address Modify/Delete Reply

    안녕하세요~ 연락처가 어디 없으셔서 이렇게 댓글 남깁니다. SharePoint를 파일시스템에 백업을 받아야하는 급박한 회사업무가 생겼습니다. 좀 도움을 얻을수 있을까요? 부탁드리겠습니다. 혹시 몰라 제 이메일 주소를 남깁니다. e.joe@samsung.com 연락 부탁드리겠습니다. 감사합니다.

  2. 2014.02.03 18:14 Address Modify/Delete Reply

    비밀댓글입니다

MonoDevelop 한글판이 곧 업데이트 됩니다.

다운로드 : http://monodevelop.co.kr

MonoDevelop 통합 개발툴의 한글화를 위해 Github에 Pull Request로 게시하였고, 몇 일 후 특별한 문제 없이 MonoDevelop Master 브랜치에 병합이 완료 되었습니다.

[Ide] Translate to Korean language

차후 공식적인 배포에 의해 Xamarin Studio, MonoDevelop, MonoDevelop for Unity 와 같은 개발툴에서 한글 버전을 만나뵐 수 있을 것 같네요.

GitHub MonoDevelop Korean Repository

오탈자 및 버그 신고

Xamarin의 공식적인 버그 신고는 https://bugzilla.xamarin.com/ 에서 신고할 수 있습니다. 다만, 한글 번역과 관련된 버그를 처리해 줄지 모르겠네요.

  1. http://monodevelop.co.kr/ 에서 신고해 주시거나

    또는

  2. GitHub MonoDevelop Korean Repository 에 신고해 주시거나

    또는

  3. 직접 MonoDevelop Repository 에서 Fork 하셔서 작업하시면 됩니다.


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 컴포지트 2013.08.05 09:09 Address Modify/Delete Reply

    군말없이 merge 시켜주다니..ㅋㅋ
    노고에 감사드립니다.

  2. hellojin 2014.02.11 17:33 Address Modify/Delete Reply

    맥용 xamarin studio 를 사용하려하는데. 한글을 입력하면. 그냥 죽어버리는 군요.. 그래서. 한글화 된걸 사용해보고 싶은데.. 어떻게 해야되는지 통 감이 안오네요.. 어떻게 해야되는지 좀 알려주세요..~ 부탁드립니다.

    • 땡초 POWERUMC 2014.02.12 09:23 신고 Address Modify/Delete

      오 그래요?
      저는 같은 맥에서 죽지 않고 잘 써지는데요...

      기본 내장 외 한글 입력기를 쓴다거나 다른 이유가 있을 것 같은데,
      덤프를 떠주시면 제가 한번 봐 드리겠습니다.

  3. oiziee 2014.03.07 18:07 Address Modify/Delete Reply

    안녕하세요 위에 링크가 죽어있네요
    한글버전을 꼭 구하고 싶은데
    한글버전을 보내주실수 있으신가요?
    부탁드립니다
    pijunyel@naver.com

    • 땡초 POWERUMC 2014.03.07 18:24 신고 Address Modify/Delete

      한글버전은 Xamarin Studio에 함께 배포 되고 있습니다.
      아래의 링크에서 받으시고,
      환경 설정의 Language에 'Korean' 으로 변경해 주시면 됩니다.

      http://xamarin.com/download

  4. 지나가던이 2014.08.05 10:24 Address Modify/Delete Reply

    한글 버전 주석은 너무나도 감사드립니다.
    하지만, 버그가 있더군요... 조금 아쉽습니다.

    '아'를 입력할경우 '아'를 입력한 후에도 한번 더 무언가를 입력해주어야만 해결되는 현상이 있습니다.

    더 좋은 버전 기대하겠습니다.

  5. TeemoSoft 2015.01.07 01:37 신고 Address Modify/Delete Reply

    안녕하세요 맥에서 유니티 모노디벨롭 을 사용중인데 http://monodevelop.co.kr에서 받아서 사용해보니
    Assembly-UnityScript 로드 실패
    Assembly-UnityScript-firstpass 로드 실패

    이렇게 뜨네요 작업하는데는 큰 문제는 없지만 어딜 고치면 될까요?

MonoDevelop for Korean version..!

MonoDevelop은 ECMA 표준을 가장 완벽하게 구현한 Mono 플랫폼을 개발하기 위한 통합 개발 도구 입니다.

2011년경, Xamarin 기업에 인수합병 되면서 모바일에 강력하게 대응되는 플랫폼으로 한 단계 진화하였습니다. iOS, Android 외에 콘솔 게임 개발도 지원하게 되었습니다.

https://github.com/powerumc/monodevelop_korean

현재 진행 사항입니다.

  • POSIX에서 재정한 Gettext API에 대응되는 .po 한글화 작업이 거의 완료가 되었습니다.
  • 한글을 지원하기 위해 MonoDevelop 내부 코드가 변경되었습니다.
  • 한글화에 따른 알 수 없는 크래시가 발생하여 디버깅 중입니다.
  • 다음 주 중으로 안정성 테스트 및 한글화 품질 테스트를 진행할 예정입니다.
  • 테스트 이후 공식적인 배포 사이트를 개설할 예정이며,
  • Mono Community 에 제출될 예정입니다.

많은 응원과 기대 부탁 합니다.

진행중인 MonoDevelop (Xamarin Studio) 스크린 샷




Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 김영환 2013.07.25 14:54 Address Modify/Delete Reply

    앗!!!!

    감사합니다.
    화이팅!!!

  2. 컴포지트 2013.07.25 17:01 Address Modify/Delete Reply

    일본어와 중국어 번역은 이미 끝났는데 오늘 한글화 소식을 들으니 이런 꿀같은 소식이!
    정말 감사합니다.

    근데 이툴이 한글 깨져요. 맥이나 리눅스나 둘다 한글 깨져요..
    이건 어떻게 해결 됐나요?

  3. 컴포지트 2013.07.26 18:19 Address Modify/Delete Reply

    인코딩 어떻게 지정하던 한글 입력이 안됩니다. 출력도 문제고 입력조차 어려운 실정입니다. 아예 이스케이프 해야지 됩니다..

    • 엄준일 2013.07.27 00:24 Address Modify/Delete

      한글 입력이 깨진다는게
      입력할 때 'ㅎㅏㄴㄱㅡㄹ' 이렇게 입력 되는 것을 말씀하시는 거죠?

  4. kmshts 2013.07.31 01:06 Address Modify/Delete Reply

    저도 이파일을 받아봤음좋겠는데 어디서 받아볼수있습니까? po파일만

    • 엄준일 2013.07.31 04:19 Address Modify/Delete

      Github에서 monodevelop_korean 브랜치에 있습니다.
      https://github.com/powerumc/monodevelop_korean/tree/monodevelop_korean

      위의 링크 파일 4개 중에 하나예요.

JS-Lambda 자바스크립트 라이브러리를 공개합니다.


JavaScript Array Extensions 자바스크립트 오픈 소스를 개발한 데 이어 JS-LambdaLGPL 라이센스로 공개합니다.

JavaScript 에서 람다 표현식(Lambda Expression)을 사용할 수 있도록 만든 라이브러리 입니다. 자세한 내용은 아래의 소스 코드를 참고 하시면 됩니다.

Github: https://github.com/powerumc/js-lambda

JS Lambda

  • It is possible lambda expression that can be used JavaScript.
  • you just got a function F();

Simple Examples

// Before  
function func(a,b) {
    return a + b;
}  
console.info( func(4,6) );


// ** After with JS-Lambda **  
var func = F("a,b => a + b");  
console.info( func(4,6) );  

// Result  
10

Or you can invoke directly

// Before  
function anonymousMethod(a,b) {
    return a + b;
}  
console.info( anonymousMethod(4,6) );  

// ** After with JS-Lambda **  
console.info( F("a,b => a + b")(4,6) );  

// Result  
10

Callback Examples

// Before  
function callback( func ) {
    if( func ) func();
}  

callback( function() { console.info('My name is Junil Um'); } );  

// ** After with JS-Lambda **  
callback(  F("() => console.info('My name is Junil Um');")  );  

// Result  
My name is Junil Um  

With jQuery

// Before  
var li = $("item li");  

li.each( function(i, o) {
    $(o).addClass("some");
} );


// ** After with JS-Lambda **  
var li = $("item li");  

li.each( F("(i, o) => $(o).addClass('some');") );  


Posted by 땡초 POWERUMC

댓글을 달아 주세요

VSGesture for Visual Studio 2013 Preview 배포 완료

Visual Studio 2013 Preview 버전 배포 완료

기능적으로 향상된 것은 없습니다. 이번 버전의 Visual Studio 2013의 Extension Schema가 골때리게 바껴서 ;;

Visual Studio 2013의 Tools -> Extension Manager 에서 다운로드 받으실 수 있습니다. (검색: vsgesture)

Download : http://visualstudiogallery.msdn.microsoft.com/e03c91ff-e20d–4dcc–822b–172a68c40f5b

  • Version 12.0 [2013/07/17]
    Support Visual Studio 2013 Preview

  • Version 11.11 [2012/03/01]
    Modified wrong display texts.

  • Version 11.1
    Resolved compativility bug between VS2012 and VS2010.

  • Version 11.0
    Support Visual Studio 2012, 2010

VSGesture shipped for Github. https://github.com/powerumc/vsgesture
VSGesture for VS2012, VS2010 is now available for download.
http://blog.powerumc.kr/305

VSGesture can execute command via mouse gestures within Visual Studio.
If you have any feedback, please send me an email to powerumc at gmail.com.

Visual Studio 2005, 2008 version : http://visualstudiogallery.msdn.microsoft.com/en-us/F5007932–0720–492B–8A51–631D5265F6B7




Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 설치가 안됩니다 2013.09.04 22:37 Address Modify/Delete Reply

    안녕하세요
    확장 관리자를 통해서 다운 받을려고 하는데,
    종속성 경고 - 다음 참조가 있어야 설치를 계속 할 수 있습니다. - Visual studio MPF 라는 팝업창이 뜨면서 설치가 안됩니다. 이거 어떻게 해야 하나요?

    참고로 윈도우7 64bit, visual studio 2010사용하고 있습니다.

[퀴즈] 프로그래머를 위한 문제 #3

요즘 퀴즈를 풀다보니 재미가 들렸나, 필자가 문제를 하나 내보려고 한다. 어려울 수도, 그렇지 않을 수도 있는 문제이며, 효율적인 코드를 작성하는 것 보다 최대한 짧게 짜는 것이 목적이다.

문제의 유형과 정답의 유형은 지난 문제를 참고하면 된다.

미로 찾기 게임

문제는 미로 찾기 게임이다.

  1. 10 x 6 (가로, 세로) 크기에 * 문자가 채워진 직사각형
  2. 미로의 크기가 변해도 실행 가능해야 한다.
  3. 문자 S 는 입구 위치, 문자 E는 출구 위치이다.
  4. S 문자와 E 문자 사이에는 공백으로 연결된 길이 있고, 길은 여러 갈래일 수 있다.
  5. 길(공백)은 2x2(가로, 세로) 이상의 공간을 가질 수 없다.
  6. 미로 찾기를 시작하는 함수가 호출되기 이전의 초기화를 위한 코드는 코드 길이에서 제외된다.
  7. 코드 길이는 최대한 짧게 작성한다. (알고리즘 효율성은 측정 안함)
  8. 개발 언어는 무관, 언어별로 가장 짧게 작성한 코드가 우승(?)



미로 찾기 게임 예제 코드

// 아래의 변수의 초기화는 코드 길이에서 제외된다.  
map = """  
**********  
** **    E
*   * ****
* * * *  *
* *    * *
S ****   *  
**********"""

y = map.indexof("S") / maxX
x = map.indexof("S") % maxX  

// 아래 코드 부터 코드 길이를 잰다. 개행 문제는 코드 길이에서 제외  
void explore(x,y)
{
    // ...생략...
}  

정답

아래는 필자가 작성한 코드이다. 짧게 작성하는 방법은 여러 가지이므로 혹시 여러분들께서 C++ 또는 자바스크립트, C# 등으로 작성하신 코드는 댓글로 달아주세요.

Python( 파이썬 )

아래 주석의 begin code/end code 사이의 문자는 총 273 문자. 방향에 대한 가중치를 주면 훨씬 빠르게 길을 찾을 수 있지만, 여기에선 구현을 제외했다.

#123456789
m = """  
**********  
** **    E
*   * ****
* * * *  *
* *    * *
S ****   *  
**********"""

X = m.index("\n", 1) - 1
Y = m.count("\n") - 1
m = m.replace("\n", "")  

(y, x) = divmod(m.index("S"), X)  

### 총 273 바이트 ###  
########### begin code ############  
def E(x,y,a):  
 n=m[x+(y*10)]  
 if n=="*"or x<0 or x>X or y<0 or y>Y:return None

 # print "%d, %d" % (x, y)  
 if n=="E": print("END");quit()

 while a!=2 and E(x+1,y,1)!=None:pass  
 while a!=1 and E(x-1,y,2)!=None:pass  
 while a!=8 and E(x,y+1,4)!=None:pass  
 while a!=4 and E(x,y-1,8)!=None:pass  

E(x,y,0)  
############# end code ##############


## 실행 결과 ##  
0, 5  
1, 5  
1, 4  
1, 3  
1, 2  
2, 2  
3, 2  
3, 3  
3, 4  
4, 4  
5, 4  
6, 4  
6, 5  
7, 5  
8, 5  
8, 4  
8, 3  
7, 3  
5, 3  
5, 2  
5, 1  
6, 1  
7, 1  
8, 1  
9, 1  
END  


Posted by 땡초 POWERUMC

댓글을 달아 주세요

프로그래머를 위한 문제 #2

얼마 전 OKJSP 를 통해 이런 문제를 보았다.

문제는 아래의 코드 중 /* INPUT */ 주석에 알맞은 코드를 넣어, victory() 메서드가 호출되도록 완성하여라.

필자의 컴퓨터에서는 답이 (function-48)(); 로 나왔다. 

typedef int (*f)(); 
int variable = 1;   

int function() {     
   if(variable == 1 ) return 
      /* INPUT */       
   5; 
   victory();  
}   

int main() 
{     
   function();
   return 0; 
}  

[문제 코드] 위의 INPUT 주석에 알맞은 코드를 넣어라.

단 제약 조건이 있습니다.

  • 다음의 문자는 사용할 수 없음 : main, victory, asm, %, *, _, #, /, “, ‘
  • 최대 11자
  • 세미콜론(;)은 한 번만 써야 함

문제 해결 과정 #1

일단 Visual Studio 2012 C++ 로 작성한 코드인데, 이 코드는 답을 찾아가기 위한 중간 코드이다.

이 코드를 보자마자 ‘스택 프레임(Stack Frame)’을 이용해야겠다는 맘을 먹고 코드를 작성했다. Visual Studio에서 만든 C++ 프로젝트의 속성으로 들어가서 RTC 런타임 체크 기능을 꺼야 한다. 그렇지 않으면 스택을 덮어 쓸 수가 없이, AccessViolation 오류가 발생할 것이다.

프로젝트 속성 -> 구성 속성 -> C/C++ -> Code Generation -> Basic Runtime Checks -> Default 로 변경

#include "stdafx.h"  
#include <iostream>  

using namespace std;  

int victory()
{
    cout << "victory" << endl;
    return 0;
}  

typedef int (*f)();  
int variable = 1;  

int function()
{
    int a;
    int n = (int)(&a) + 8;// 일반적으로 스택은 위로 자라므로,  EBP + 4 의 위치를 구함

    // victory 메서드 시작 위치는 현재로 부터...  765임
    cout << (int)(&victory) - (int)(&function) << endl;  
    *(void**)n = (void*)((int)(&function) - 765);    

    if(variable == 1 ) return
    /* INPUT */ 
    5;
    victory();
}  

int _tmain(int argc, _TCHAR* argv[])
{
    function();
    return 0;
}  

// 실행 결과  
// -765  
// victory  

대충 그림이 나왔으니 코드를 /* INPUT */ 에 들어갈 수 있도록 예쁘게 다듬어주면 될거라고 생각했다. 그런데 VC++은 타입체크가 너무 강한지 몰라도 어떻게 예쁘게 다듬어도 오류가 난다. 줸장~ 문제와는 상관 없이 좀 더 만져봐야 겠다.

문제 해결 과정 #2

오늘 정성태 과장님이 이 문제를 보고 이야기를 나누었고 답을 보여주셨다. 답은 링크를 통해 방문하면 된다.

과장님 왈, VC++ 에서는 컴파일이 안될거라고, GCC에서 컴파일 했다고 알려주셔서 나도 얼른 GCC로 바꿨다. 궁극적으로 위의 문제 해결 과정 #2 방법을 GCC로 간결하게 표현했다. 어쨌든 정성태 과장님과 답이 거의 같다.

정성태 과장님이 아니었으면 VC++만 가지고 매달렸을텐데, 문제를 풀 수 있도록 도와주신 울 과장님께 ㄱㅅ ㄱㅅ ^^

# include <stdio.h>  

int victory()
{
    printf("victory\n");
    return 0;
}


typedef int (*f)();  
int variable = 1;  

int function()
{
    // victory 메서드가 얼마만큼 떨어져있나 찍어봄... 48만큼...
    printf("%d\n", &function - &victory);  


    if(variable == 1 ) return

        (function-48)();      /* <------- INPUT CODE */
    ;

    5;

    victory();

}  

int main(int argc, const char * argv[])
{
    printf("---------------\n");
    function();
    return 0;
}   

// 실행 결과  
48
victory  


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. orbit 2016.12.20 14:16 Address Modify/Delete Reply

    재미있는 글이네요
    저는 VS2015에서 이렇게 풀었습니다.

    #include "stdafx.h"
    #include "victory.h"

    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif

    #include <iostream>

    int victory()
    {
    std::cout << "victory" << std::endl;

    return 0;
    }

    typedef int(*f)();
    int variable = 1;

    int function() {

    f foo = (f)((int)function - ((int)function - (int)victory));

    if (variable == 1) return
    /* INPUT */ foo();
    5;
    victory();
    }

    int main()
    {
    function();
    return 0;
    }

프로그래머를 위한 문제

프로그래머라면 알쏭달쏭한 논리적인 문제를 좋아하는 편인 것 같다. 답이 팍~ 나오는 문제보다 역량에 따라 코드의 아름다움이 달라지는 것을 추구하는 프로그래머라면 더욱 그렇다.

문제: 1부터 1만까지 8은 모두 몇 개가 나오나?

문제는 쉽다. 1부터 1만까지 8이라는 문자 개수만 카운팅하면 된다. 그런데 이렇게 간단한 문제를 코딩해 놓고 보면 맘에 안든다. 더 짧게…. 아래의 문제를 각 언어별로 풀어보았는데, 바이트 수는 캐러지 리턴(carriage return) 문자를 모두 제거한 바이트 수이다.

참고로, 이 문제는 ‘닷넷(.NET) 프로그래머 모임’ 에서 처음 본 문제인데, 오래 전의 일이라 게시글의 링크를 도저히 찾기가 힘들어서 링크를 남기지 못했다.

여러분 중 문제를 풀어보려고 한다면, 바로 아래에 답이 있으니 브라우저를 먼저 종료하길 바란다.

파이썬(python)

파이썬을 배운지 얼마 안되던 때에 이 문제를 만나서 파이썬으로 풀어보았다. 누가 짜도 최종적으로 아래의 코드가 될거다. 처음에는 이렇게 짧게 가능한 파이썬이 맘에 안들었지만, 이제는 맘에 든다. ㅋ;

더 이상은 짧게 안되지 싶다.

# 총 38 바이트   
(str(list(range(1,10001))).count('8'))  

C#

C# 코드로 짜면 아래처럼 된다. 아래의 코드는 확장 메서드와 람다 표현식이 전부다.

혹시나 요걸 비트 연산으로 풀어봤는데, 아래 코드보다 길어지더라. 뭐 내가 짠 코드라 길어질 수도 있겠다.

// 총 84 바이트  
Console.WriteLine(Enumerable.Range(1,10000).Sum(o=>o.ToString().Count(n=>n=='8')));   

Java

Java 8 정식이 나오면 Lambda 지원. 다만 C#의 확장 메서드를 언어상 지원하지 않으므로 Where, Select, Take, Skip 과 같은 확장 메서드는 사용하지 못할 것 같다. 어쨋든 Java 로 이 문제를 짧게 풀수 있는 경쟁력이 없으므로 패스!

C++ Update - 2013-07-04

C++에 대해 조예가 깊지 않아서 내 머리로는 더 짧게 안된다. 이 코드는 위의 파이썬과 C#과는 알고리즘(?)이 좀 틀리다. 어쩔 수 없다. 짧게 하려면…

// 총 146 바이트  
vector<int> v(10000);  
auto n=1,s=0;  
generate(v.begin(),v.end(),[&n, &s](){  
auto m=to_string(n);  
s+=count(m.begin(),m.end(),'8');  
return n++;});  
cout<<s;

아래 댓글에 더 짧은 C++ 코드를 올려주신 HATENA [링크] 님께서 올려주신 코드 입니다. Update - 2013-07-04

// 총 94 바이트
int c=0;
for(int i=1;i<10001;i++){
auto s=to_string(i);
c+=count(s.begin(),s.end();'8');}
cout<<c;

JavaScript - Update 2013-07-03

본 코드는 아래 댓글의 ddd 님께서 작성하신 자바스크립트 코드 입니다.

// 총 94 바이트  
var a=[];
for (var i=1;i<10001;i++)
a[i]=i;
console.info(a.join("").replace(/[^8]/gi,"").length);
Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 황정현 2013.07.02 09:33 Address Modify/Delete Reply

    예전에 자바스크립트로 한번 풀어봤었네요... 근데 너무 길어요...
    for(var i = 0, len = 10000, count = 0, tmp = ""; i < len; i++){
    var arr = [];
    tmp = (""+i);
    for (var j = 1, len2 = tmp.length; j <= len2; j++)
    {
    arr[j] = tmp.substring((j - 1), j);
    if(arr[j].indexOf("8";) > -1) count++;
    }
    }
    console.log(count);

  2. ddd 2013.07.03 17:53 Address Modify/Delete Reply

    javascript 는 이정도 면 될듯한데
    var a = [];
    for (var i = 1; i < 10001; i++)
    a[i] = i;
    alert(a.join("";).replace(/[^8]/gi, "";).length);

    javascript 는 반복문 안쓸수 없나요 ㄷㄷ

    • 엄준일 2013.07.04 10:28 Address Modify/Delete

      댓글로 적어주신 소스 코드를 제 포스트에 업데이트 했습니다.
      ddd 님 사이트 링크를 남기고 싶었는데,
      링크가 없어서 아쉽네요 ㅠ

  3. HATENA 2013.07.04 11:27 Address Modify/Delete Reply

    항상 블로그 잘 보고 갑니다.
    C++은 vector, generate 안써도 쉽게 풀릴거같은데요 ㅎㅎ.

    int c=0;
    for(int i=1;i<10001;i++){
    auto s=to_string(i);
    c+=count(s.begin(),s.end();'8');}
    cout<<c;

    요거면 100byte 이내로 끝날거같습니다.
    파이선 코드길이 ㅎㄷㄷ하내요 ㄷㄷㄷ

  4. java론 2014.01.07 15:46 Address Modify/Delete Reply

    자바로는 아래처럼....
    int a=0;
    for(int i=0;i<10001;i++) {
    a+=(""+i).replaceAll("[^8]","";).length();
    }

  5. 김인혜 2014.04.06 03:56 Address Modify/Delete Reply

    마이너한 스크립트 언어입니다.
    AutoHotkey

    Loop 10000
    _ .= A_Index
    Msgbox % RegExReplace( _, "8", "", @ ) ? @ :

  6. 지나가다 2015.12.15 15:03 Address Modify/Delete Reply

    만들고 나니 위분거랑 같네요 ㅡㅡ;
    int result = 0;
    for (int i=0; i<=10001; i++) {
    result += String.valueOf(i).replaceAll("[^8]", "";).length();
    }
    return result;

  7. 행인 2016.11.20 15:28 Address Modify/Delete Reply

    Acm 문제에서 간간히 등장하는 유형이네요.
    그 당시 풀때 속도 문제 때문에 reject떠서 수학적으로
    규칙을 찾아서 accept 받았던 기억이 나네요

  8. 재밌네요 2016.11.29 16:02 Address Modify/Delete Reply

    Javascript 좀더 짧게~
    --------------------------------------
    var i,s,r; for (i = 1; i < 10001; i++) s += '' + i; r = s.split('8').length-1;
    console.log(r);

jQuery 1.7.1 버그 패치를 공유합니다.

jQuery 1.7.1 의 정식 버전은 인터넷 익스플로러(IE; Internet Explorer) 10 버전에서 런타임 버그가 존재한다. 이 버그는 jQuery 1.7.1 내부적으로, 그리고 jQuery UI 에 영향을 미친다.

그러므로 현재 jQuery 1.7.1 버전을 사용하는 버전에서는 필자가 공유한 코드를 사용하거나 패치 방법으로 코드를 수정하면 된다.


다운로드 및 추가정보






Posted by 땡초 POWERUMC

댓글을 달아 주세요

구글에서 활동한 내 모든 정보 백업 받기

최근 구글이 리더 서비스를 종료하면서 필자도 구글 리더 백업을 시작했다.

구글 리더는 OPML로 RSS 목록을 내보내려면 구글이 아닌 다른 서비스의 도움이 필요합니다만, 다음과 같은 방법으로 구글에서 활동한 자신의 모든 정보까지 백업 받을 수 있다. 구글리더, 구글 플러스, 구글 드라이브, 유튜브에 업로드한 동영상, 주소록, 리더 OPML 등 거의 모든 데이터를 다운로드 받을 수 있다.

  1. 구글 사이트에 로그인 후 ‘계정’ 클릭
      

  2. ‘내 데이터 다운로드’ 클릭
      

  3. ‘내 데이터 다운로드’ 클릭
      

  4. 테이크 아웃의 하단에 ‘보관함 만들기’ 클릭
      

  5. 구글이 내 데이터를 모으는 중…
      

  6. 준비가 되면 ‘다운로드’ 클릭
      

  7. 다운로드 된 압축 파일을 풀면 된다.
      


Posted by 땡초 POWERUMC

댓글을 달아 주세요


필자는 최근 자바스크립트(Javascript)를 자주 만지게 되면서 몇 가지 팁 또는 가이드 정보를 공유하고자 한다. 자바스크립트(Javascript)를 좋아하지만 잘 하지는 못한다. 그래서 먼저 개념적으로 잘못된 부분이 있으면 정중하게 미리 양해를 구하고자 한다.

1. 익명의 즉시 실행 함수로 스크립트를 시작하자

익명(Anonymous)의 즉시 실행 함수(Immediately Invoked Function Expression)는 다음의 코드와 같이 정의된다.

(function() {
       // ... 코드 생략 ...  
}());  

익명 함수(Anonymous Function)는 자바스크립트(Javascript)가 런타임(Runtime)에 구문을 해석하여 실행한다. 이는 외부의 접근을 제한함을 의미한다. 그러므로 외부 코드에서 익명 함수의 내부 코드를 임의적이나 악의적으로 수정할 수 없다.

즉시 실행 함수(Immediately Invoked Function Expression)는 선언과 동시에 실행이 된다. 익명 함수가 런타임에 사용될 준비가 되면 즉시 함수의 초기화 코드를 실행할 수 있기 때문이다. 예를 들어, 아래와 같은 코드는 악의적으로 전역 변수의 영향을 받지 않도록 함수(Function) 을 보호할 수 있다.

만약 익명 함수에 정의된 undefined 매개 변수에 진짜 undefined 가 전달되기를 기대하는 경우가 있는데, 즉시 실행 함수(Immediately Invoked Function Expression) 중간에 undefined = true 에 의해 원하는 결과를 얻을 수 없게 된다.

var undefined = true;  

(function(undefined) {
   console.info(undefined);
   console.info(undefined === true);  
})(undefined)  

// 실행 결과  
true  
true  

만약, 외부 코드에 의해 undefined 가 완벽하게 변경되길 바라지 않는 경우 다음과 같이 undefined 가 반환되는 결과를 매개변수로 사용하여 외부 코드에 의한 원치 않는 결과의 충격에서 보호할 수 있게 된다.

var undefined = true;  

(function(undefined) {  

console.info(undefined);  
console.info(undefined === true);  

})( function() {}() );  

// 실행 결과  
undefined  
false  

2. 모듈화 패턴은 한 가지만 사용하라

Javascript 를 모듈화하기 위한 패턴은 여러 가지 방법이 있다. 그런데 여러 패턴을 섞어 사용하다 보면 코드를 보기가 더 난해해 진다. 때문에 필자는 private과 public 접근 제한 방법을 제공하는 모듈 패턴(Module Pattern)을 주로 사용한다. [1]

이 외에도 효과적인 패턴들이 많이 존재하므로 적당한 패턴을 선정하여 모두가 함께 같은 패턴으로 사용하는 것이 현명할 것 같다.

var umc = umc || (function() {

    var privateFunction1 = function() {
        // ... 생략 ...
        return true;
    };

    return {
      "version"   : "3.0.0.0",
      "name"      : "Umc.Core Frameworks",
      "getObject" : function() {
          var result = (privateFunction1() ? "POWERUMC" : "HTTP://BLOG.POWERUMC.KR");
          return result;
      }  
};
})();  

console.info( umc.version );    // 결과 : 3.0.0.0  
console.info( umc.name );      // 결과 : Umc.Core Frameworks  
console.info( umc.getObject() );    // 결과 : POWERUMC     
console.info( umc.privateFunction1() );    // 오류  

[코드1] Self-Contained 모듈화 패턴

var umc = umc || (function() {  

   var _version = "3.0.0.0";
   var _name = "POWERUMC";
   var _getObject = function() { /* 코드 생략 };

   return {
      "version"   : _version,
      "name"      : _name,
      "getObject" : _getObject
   }  
})();  

[코드2] Imports 모듈화 패턴

var umc = umc || (function() {  

   var module = { };

   var _version = "3.0.0.0";
   var _name = "POWERUMC";
   var _getObject = function() { /* 코드 생략 };

   module.version = _version;
   module.name = _name;
   module.getObject = _getObject;

   return module;  
})();  

[코드3] Exports 모듈화 패턴

모듈 패턴(Module Pattern)을 정의하는 방법은 몇 가지가 있다.

  1. Self-Contained
    바로 위의 예시로 제시한 코드가 바로 Self-Contained 인데, public 함수를 직접 구현하는 방법이다.

  2. Imports-mixin
    아래와 같은 코드가 Imports 하는 방법으로 정의하는 모듈 패턴(Module) 패턴이다. 코드는 return 코드 부분만 보면 된다.

    1번과 2번의 경우는 함수가 익명(Anonymous) 함수로 정의 된다.

  3. Exports
    아래와 같은 코드는 module 을 외부로 공개하여 쉽게 확장이 가능하도록 한다.

3. 함수의 매개변수는 맨 먼저 초기화 하라

자바스크립트(Javascript)는 매우 관대하다. ‘오래 꽥꽥(Duck Typing)’은 동적 언어(Dynamic Languages)의 가장 큰 매력이라고 할 수 있다. 혹시라도 강아지가 ‘꽥꽥’ 거리면 자바스크립트는 강아지를 오리로 취급한다.

정의되지 않은 변수나 매개변수(Arguments), 아래의 코드 처럼 write("ERROR"); 와 같이 매개 변수의 개수가 맞지 않아도 너그럽게 실행이 된다. 하지만 코드에 정의되지 않은 undefined에 의해 실행은 얼마든지 오동작이 가능하므로, 가능하면 매개변수는 항상 올바르게 넘겨주지 않는다는 가정하에 작성하는 것이 좋다.

만약, message = message || "-";과 같이 초기화 또는 방어 코드가 없다면 로그는 ''Sun Jun 02 2013 13:05:38 GMT+0900 (KST) : ERROR / undefined 와 같은 결과를 보여준다.

var write = function(category, message) {

    category = category || "INFO";
    message  = message  || "-";

    var date = new Date();;

    console.info( date + " : " + category + " / " + message );  
};

write("INFO", "시작 메시지");  
write("WARN", "경고 메시지");  
write("ERROR");  

// 실행 결과  
Sun Jun 02 2013 13:05:38 GMT+0900 (KST) : INFO / 시작 메시지  
Sun Jun 02 2013 13:05:38 GMT+0900 (KST) : WARN / 경고 메시지  
Sun Jun 02 2013 13:05:38 GMT+0900 (KST) : ERROR / -  

4. 매개변수가 있지만 없어도 동작하도록 해라

함수의 매개변수는 맨 먼저 초기화 하라’ 에서 본 write("ERROR"); 와 같이 매개 변수가 맞지 않아도 잘 동작하도록 방어적인 초기화 코드를 작성하였다.

하지만, write(); 의도적으로 호출을 할 경우 다음의 코드처럼 올바르게 로그 기록이 남지 않게 된다.

write("실행 종료");  

// 실행 결과  
Sun Jun 02 2013 13:14:01 GMT+0900 (KST) : 실행 종료 / -  

category 에 로그 형식이 전달되어야 하는데, 로그 메시지 ‘실행 종료’가 category 항목으로 초기화되어 엉뚱한 결과가 나오게 된다.

이런 경우는 좀 더 매개 변수가 전달되는 가능성을 좀 더 열어두어, 매개 변수의 개수에 따라 매개 변수를 직접 할당하도록 하는 아래의 코드와 같은 방법을 사용하면 된다.

var write = function(category, message) {

    category = category || "INFO";
    message  = message  || "-";

    if( arguments.length === 1 ) {
        message = category;
        category = "INFO";
    }

    var date = new Date();;
    console.info( date + " : " + category + " / " + message );
}  

write("INFO", "실행 시작");  
write("WARN", "실행 중 경고");  
write("실행 종료");  
write();  

// 실행 결과  
Sun Jun 02 2013 23:20:44 GMT+0900 (KST) : INFO / 실행 시작  
Sun Jun 02 2013 23:20:44 GMT+0900 (KST) : WARN / 실행 중 경고  
Sun Jun 02 2013 23:20:44 GMT+0900 (KST) : INFO / 실행 종료  
Sun Jun 02 2013 23:20:44 GMT+0900 (KST) : INFO / -  

5. 띄어쓰기 스타일(Intent Style)은 반드시 K&R Style 을 사용하자.

K&R 스타일은 전세계의 커뮤니티에 따라 다르지만, C, C++, C#, Java 등의 언어에서 사용된다고 한다. 참고로, 마이크로소프트(Microsoft)가 추천하는 띄어쓰기 스타일은 ‘Allman Style’ 이라고 부른다.

위키피디아(Wikipedia)에 따르면 K&R 스타일은 다음과 같은 유래가 있다고 한다.

The K&R style, so named because it was used in Kernighan and Ritchie’s book The C Programming Language, is commonly used in C. It is also used for C++, C#, and other curly brace programming languages.

K&R 스타일의 이름의 유래는 Kernighan씨와 Ritchie씨의 저술서 The C Programming Language의 C 코드에서 일반적으로 사용했다. 또한 C++, C#, 그리고 중괄호(curly brace)를 사용하는 프로그래밍 언어에서도 K&R 스타일을 사용한다.

자바스크립트(Javascript)는 K&R 스타일의 띄어쓰기 스타일을 사용한다.

필자는 자바스크립트에서 K&R 스타일을 추천하는 것이 아닌, 반드시 K&R 을 쓰는 것이 좋다고 믿는다. 다음의 코드를 보면 왜 K&R 스타일을 사용하는지 알 수 있다.

// K&R 띄어쓰기 스타일  
function getdata\_1() {  
return {
    name: "POWERUMC"  
};
}  

// Allman 뜨어쓰기 스타일  
function getdata\_2()
{  
return
{
    name: "POWERUMC";
}
}  

console.info("getdata_1() - " + getdata_1());  
console.info("getdata_2() - " + getdata_2());  

// 실행 결과  
getdata_1() - [object Object]     // 올바른 결과  
getdata_2() - undefined     // 올바르게 return 되지 않은 결과  

결론

이 외에도 몇 가지 더 있지만, 자바스크립트(Javascript) 내공을 좀 더 쌓은 후에 더 정확하게 쓰는 것이 낫겠다고 생각하여 5개의 팁 정도를 공유했다. 하지만, 예제로 제시한 코드에 대해 성능적인 면이나 익명 함수 또는 즉시 실행 함수 등의 메모리 누수 등에 대해서는 언급하지 않을 예정이다.

내용면으로 부족한 부분이 있겠지만, 이 정도의 팁과 가이드면 바로 현업에서 깔끔하고 잘 동작하는 자바스크립트(Javascript) 코드를 작성하기에는 전혀 문제가 없다고 생각한다.

디자인 패턴(Design Pattern) 부분에서 더 많은 정보를 얻길 원한다면, 필자의 언급한 ‘Learning JavaScript Design Patterns A book by Addy Osmani Volume 1.5.2’ 를 참고하기 바란다.


  1. Module Pattern 참고 : Learning JavaScript Design Patterns
    http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript  ↩


Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 2013.06.24 11:41 Address Modify/Delete Reply

    비밀댓글입니다

  2. 2015.05.22 23:56 Address Modify/Delete Reply

    비밀댓글입니다

    • 땡초 POWERUMC 2015.06.13 21:38 신고 Address Modify/Delete

      함수 안에 매개변수를 선언하는 것이 아닙니다.
      변수에 대입(assign) 하는 것이죠 ^^
      변수는 이미 함수 매개변수에 선언이 되어있으니까요.

  3. 2015.08.07 14:27 Address Modify/Delete Reply

    비밀댓글입니다

  4. 나그네 2017.09.15 13:13 Address Modify/Delete Reply

    [코드3] Exports 모듈화 패턴 에 name 오타가 있네요. 감사합니다

불완전한 통합, 모든 것을 만족할 수 있지만, 어느 것도 만족시킬 수 없다.

팀 파운데이션 서버(Team Foundation Server)는 모든 것을 통합한 마이크로소프트(Microsoft)의 ALM(Application Lifecycle Management) 솔루션이다.

통합… 모든 것을 만족할 수 있지만, 어느 것도 만족시킬 수 없다.이 통합이라는 것은 이 시대엔 단점으로 작용될 수도 있다는 생각이 든다. 지난 2005년부터 2010년까지 ‘통합’ 이라는 것이 장점이라고 생각했었다. 모든 것을 올인원(All in One) 해 놓았다는 것만으로 주목을 끌 수 있었지만, 2013년 최근에는 이제 더 이상 ‘통합’이 장점이 될 수 없다는 결론을 내렸다.


[이미지] 통합... 현실적인 통합과 이상적인 통합


(현실적인 통합?)
출처 : 이미지 링크

(이상적인 통합?)
출처 : 이미지 링크


필자는 비주얼 스튜디오 팀 시스템(Visual Studio Team System) 2005 버전부터 팀 파운데이션 서버(Team Foundation Server)를 사용해왔다. 필드에서는 이와 관련된 다수의 기업 컨설팅과 강의를 진행하였고, 그 외 레거시 개발 환경과 소스 컨트롤(Source Control)을 커스터마이징한 소프트웨어를 납품하는 등 대략 8년을 넘게 비주얼 스튜디오(Visual Studio)와 팀 파운데이션 서버(Team Foundation Server)와 동거동락하며 지냈다. 물론, 8년을 넘게 사용하면서 좋은 점도 많지만 그렇지 않은 점도 확실히 있다.

그 동안 한 가지 ALM 솔루션만 사용할 때는 미처 몰랐던 것들이 많았지만, 여러 가지 ALM 제품을 접하면서 ALM 솔루션 간에 장/단점을 필자의 기준에 좀 더 객관적으로 판단할 수 있는 계기가 되었다.

과거 ALM은 오픈 소스 진영을 중심으로 조금씩 발전해 왔다. SVN 소스 제어 컨트롤을 중심으로 각각 독립적인 유닛(Unit)으로 배포가 되고 플러그인 등을 활용하여 조금씩 연동을 할 수 있었다. 그런 와중에 마이크로소프트(Microsoft)는 개발툴과 ALM을 통합한 ‘팀 시스템(Team System)’ 발표하였고, 그 당시 여러 오픈 소스가 가진 것들을 한 곳에 통합하여 사용할 수 있었다. 이 때까지는 ‘통합’ 이라는 것 자체가 장점이던 시대이다.

하지만, 최근 ALM은 조직의 성숙도에 맞는 전문적인 ALM 툴을 사용하는 추세이다.

아쉽게도 팀 파운데이션 서버(Team Foundation Server)는 각각의 모든 기능들이 전문성을 갖추기에는 매우 부족한 것도 사실이다. ‘이슈 관리, 빌드, 소스 제어’, 아마도 딱 떠오르는 대표적인 벤더 및 오픈 소스들이 있을 것이다. 이슈 관리(Issue Managements), 빌드(Builds), 소스 제어(Source Control) 등, 타 벤더의 전문적인 툴과 비교하면 각각의 기능은 타 벤더에 비해 열악하다.

대표적인 ALM 벤더들과 차이가 나는 것은 마이크로소프트(Microsoft)의 팀 파운데이션 서버(Team Foundation Server)는 범용성을 추구하고, 전문적인 것들은 SDK(Software Development Kit)를 사용하여 커스터마이징을 하거나, 3rd party 벤더의 몫으로 남긴다. 대인배적인 모습이긴 하지만, 현재까지도 여전히 팀 파운데이션 서버(Team Foundation Server)를 중심으로 한 생태계가 형성되지 않았다는 것 또한 단점으로 작용한다.

필자는 최근 아틀라시안(Atlassian)의 ALM 제품에 매력을 느끼고 있다. 각각의 기능들이 매우 뛰어나고, 필요하다면 언제든지 필요한 기능의 소프트웨어와 통합이 가능하다. 설치부터 통합까지 매우 간단하다. 그리고 어떤 운영체제에서도 설치와 운영이 가능한 ‘크로스 플랫폼(Cross-Platform)’ 이라는 점은 팀이나 조직에서 선택의 폭이 넓고, 또 하나, 데이터베이스, 웹 서버 등 선택의 폭도 넓다. (반면, 팀 파운데이션 서버(Team Foundation Server)는 설치는 쉽지만 구성(Configuration)이 복잡하고 운영(Operation)에 더 많은 리소스가 필요하다)

그리하여 앞으로 필자는 여러 ALM 솔루션을 벤치 마킹하면서 ALM 솔루션들 간에 장단점 등을 비교/분석하여 함께 공유할 예정이다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

객체지향 프로그래밍 이야기

IoC(Inversion of Contol)[1], 우리말로는 ‘역전제어’라고 한다. 객체지향 프로그래밍의 기본은 만들어진 객체를 잘 쓰는 것 부터 시작한다. 이 경우 개체(Object)를 인스턴스화(Instance)하기 위해 개체(Object)를 직접 참조해야 한다.

개체(Object)는 class 로 선언되는 빌딩의 명세서(설계도?)와 같고, 인스턴스(Instance)는 만들어진 빌딩(Building-건물)을 의미한다. 전자를 개체(Object)라고 부르며, 후자를 객체(Object) 또는 인스턴스라고 부른다.

명세서를 찍어내는 방법은 매우 간단하다. Building b = new Building() 이것이 객체지향에서 개체를 인스턴스화 하는 코드가 되겠다. 그런데 현실에서의 건물은 매우 다양하다. 아파트도 있고, 오피스텔도 있고, 고층빌딩도 있다. 어떤 건물은 지하 주차장이 완비되어 있고, 어떤 건물은 주차장이 옥상에 있다. 물론 없는 건물도 있다. 어떤 건물은 건물 전체가 주차장이다.

하나의 객체로 건물의 모든 기능을 담기란 힘들다. 방, 화장실, 출입문, 엘리베이터 등 각각 작은 객체들을 기능 단위로 쪼개야 나중에 다른 건물을 지을 때도 재사용성이 높아진다. 여러개로 쪼개진 기능을 한대 묶어 복합적으로 배치하면(Complex + Composition) 오피스텔이 되기도 하고, 원룸텔이 될 수 있다. 이 얼마나 아름다운 객체지향의 세계인가.

그런데 어느 엘리베이터 업체가 가장 최신의 기능을 넣기 위해 독자 표준으로 만들었다. 이 엘리베이터는 총 중량도 검사해서 작동 여부가 결정되고, 중량이 넘어서면 목적지 까지 중간에 서지도 않는 똑똑한 지성도 갖추었다. 환풍 설비도 갖추고, 향기도 나고, 내부 벽은 고급스러운 스테인레스로 쫙 깔았다.

공포 영화에나 나올 법한 허름한 구닥다리 병원의 삐그덕 거리는 엘리베이터와는 차원이 다르다. 이 병원 건물은 환상적인 저 엘리베이터 업체의 객체를 샀다. 젠장, 안맞는다. 크기도 국제 표준의 규격과 다르고, 외벽과 연결되는 환풍 설비는 꽉 끼어 찌그러질 판이다. 마치 38인치 바지를 입는 사람이 30인치 바지를 억지로 입으려는 것과 같다.

인터페이스 지향적인 프로그래밍 이야기

이 엘리베이터 업체는 최첨단 기술이 도입되는 건설사의 수주를 받아 개발한 엘리베이터인데, 건설사와 계약이 끝나니 손가락만 빨게 생겼다. 독자 표준의 엘리베이터를 국제 표준에 맞게 다시 만들었고 이제야 다시 매출이 조금씩 오르기 시작했다.

국제 표준 규격에 맞게 정해진 규약을 지켜서 만들었다. (말도 안되는 ISOxxxxElevatorOutputV1 이라는 인터페이스가 규약이라고 치자)

public interface IStarbucksElevator
{  
    ISOxxxxElevatorOutputV1 Open();  
    ISOxxxxElevatorOutputV1 Close();

    ISOxxxxElevatorOutputV1 Up();  
    ISOxxxxElevatorOutputV1 Down();
}  

세상이 변하고 살기 좋아지면서 새로운 기술도 쏟아진다. 국제 표준 기구는 엘리베이터에 범죄 예방을 위해 CCTV 규격을 V2 에 포함시켰고, V3 버전에는 어린이들도 쉽게 버튼을 누를 수 있도록 버튼의 위치와 비상벨의 위치가 매우 낮아졌다.

이 엘리베이터 업체는 모든 최신 규격을 지키기 힘들다. 기술력 확보를 위해 인재도 뽑아야 하고, 최신 표준 규격에 맞는 부품을 수입도 해야하고, 아직 모든 준비는 되지 않았지만, 국제 표쥰은 지킬 수 있다. 이렇게 말이다.

public interface IStarbucksElevator
{  
    ISOxxxxElevatorOutputV1 Open();  
    ISOxxxxElevatorOutputV3 Close();

    ISOxxxxElevatorOutputV1 Up();  
    ISOxxxxElevatorOutputV2 Down();
}  

그리고 국제 표준 인터페이스는 하위 호환을 지켜야 하므로 이렇게 생겨먹었다.

public interface ISOxxxxElevatorOutputV1
{  
    // ... 생략 ...
}  

public interface ISOxxxxElevatorOutputV2 : ISOxxxxElevatorOutputV1
{  
    // ... 생략 ...
}  

public interface ISOxxxxElevatorOutputV3 : ISOxxxxElevatorOutputV2
{  
    // ... 생략 ...
}  

국제 표준을 지키기 때문에 명확하게 인터페이싱이 가능하지만, 이 업체의 내부 구현 코드는 점점 엄망이 되어 간다. 내부적으로 지나치게 코드의 버전이 많아지고, 또 갈리게 된다.

이 업체는 표준 규격에 맞게 제작된 엘리베이터의 종류가 여럿 있다. 소형, 중형, 대형 건물마다 필요한 엘리베이터 버전들이 많다.

이제는 엘리베이터 내부 개발자들은 객체를 생성하는 것이 점점 무서워질 정도다. 가끔 헷갈리기도 하는데, 소형 엘리베이터의 코드에서 return new ISOxxxV1LargeBuildingInternalV2_5 이렇게 대형 건물용 엘리베이터 객체를 반환했다간 아작이 난다.

인터페이스 기반의 프로그래밍은 분명한 장점이 많다. 특히 인터페이스 기반으로 다른 객체를 쓸 때 편하다. 내부적인 코드의 개선이 필요하거나 인터페이스에 살짝 변화가 온다던가, 분석이 필요한 경우 인터페이스 기반으로 구현된 코드를 보면 난독증이 올 지경이다. 특히, 인터페이스나 객체들을 이용하여 다형성을 가지는 개체들은 디버깅 기능이 떨어지는 개발툴(IDE)에서는 거의 시간과 씨름하는 노가다와 같다.

국내의 엘리베이터 적용에 관한 법이 바뀌었다. CCTV 기능이 있는 국제 표준 버전 2(ISOxxxxElevatorOutputV2) 기능이 없으면 대형 건물에 엘리베이터를 설치할 수 없다. 또 구현해서 바꿔야 한다. return eturn new ISOxxxV1LargeBuildingInternalV2_5_RequiredCCTV

객체의 생성과 파괴는 간접적 컨테이너(Container)에 의해

그렇다. 객체를 직접 생성하려고 하면 강하게 응집력이 생긴다. 그래서 인터페이스를 활용하여 응집력을 낮추었다. 근데 매우 복잡한 객체지향적인 코드에서는 인터페이스 기반은 너무 힘들다. 인터페이스가 변하지 않음을 보장하고 인터페이스의 상속의 스택이 없거나 매우 짧다면 쉽지만, 스택이 깊어지면 당연히 더 어려워질 수 밖에 없다. 디버깅 경험을 떠올려 보라. 메서드 안의 메서드(Inner Method), 또 그 안에서 또 다른 메서드 호출이 깊어지면 복잡해질 수 밖에 없다.

그래서 IoC(Inversion of Control-역전 제어)는 직접 개체를 핸들링 하던 것을 간접 참조를 통해 제어 방향을 완전히 반대로 바꾸는 방법이다.

기존의 객체를 직접 핸들링 하던 방식과 인터페이스 기반의 방식을 표현하면 아래와 같이 표현할 수 있겠다.


아래의 그림은 각각의 장점과 단점을 기술한 표이다.

IoC(Inversion of Control)에 대해 필자와 같은 돌팔이가 아닌 ‘집단 지성’의 명쾌하고 깔끔한 정의는 링크를 통해 확인하기 바란다.


Umc Core IoC 통합 컨테이너의 탄생 배경

Umc Core IoC는 여러 개의 서로 다른 프레임워크의 인터페이스와 스키마, 그리고 Dependency & Injection, AOP Weaving 의 인터페이스를 모두 통합한 프레임워크이다.

오픈 소스의 시대이다. 객체를 다루는 트랜드도 바뀌어 이 전에 아티클의 내용인 다이나믹 프록시(Dynamic Proxy) 와 AOP(Aspect Oriented Programming) 등과 같은 기법들을 사용한다.


아래 현재 버전의 오픈 소스가 참조하는 IoC 컨테이너 오픈 소스는 2011년 당시와 다를 수 있음.


문제는 오픈 소스들마다 사용하는 다이나믹 프록시 오픈 소스, IoC 컨테이너 오픈 소스가 제각기 다르다는 문제에서 출발하게 된다. NHibernate, iBatis.NET(현 myBatis.NET)Castle Windsor 프레임워크의 다이나믹 프록시 및 IoC 컨테이너를 사용하고, Enterprise LibraryUnity Application Block 프레임워크를 사용한다.

만약, Enterprise Library를 기반으로 ORM 프레임워크로 NHibernate 조합으로 사용한다고 치자. 내부적으로 객체를 생성하는 곳이 두 군데가 된다. 이 객체의 생명 주기를 관리하는 곳도 두 곳이 된다. 다이나믹 프록시(Dynamic Proxy) 개체가 생성된다면 똑 같은 개체가 두 군데에서 생성하므로 괜한 메모리 공간만 차지하게 된다.

아래의 그림은 2011년 당시 수집한 자료를 기반으로 작성이 되었다.



하나의 응용 프로그램의 레이어(Layer) 안에서 두 개의 컨테이너와 프록시 객체가 생성되는 것도 문제지만, 두 개의 프레임워크가 제공하는 인터페이스도 판이하게 다르다는 것은 코딩 스타일에 문제가 된다. 당연히 응용 프로그램 차원에서는 더 큰 문제로 보아야 된다.

아래의 그림에선 두 개의 IoC 프레임워크가 전혀 다른 XML 스키마와 인터페이스를 제공하는 것을 알 수 있다.



Umc Core IoC 프레임워크의 소스 코드는 https://github.com/powerumc/UmcCore/tree/master/Src/Base%20Frameworks/Src/Core/IoC 에서 먼저 확인할 수 있다.

To be continue #2…


  1. In software engineering, inversion of control (IoC) is a programming technique, expressed here in terms of object-oriented programming, in which object coupling is bound at run time by an assembler object and is typically not known at compile time using static analysis.  ↩

    http://en.wikipedia.org/wiki/Inversion_of_control


'Umc Projects > Umc.Core' 카테고리의 다른 글

Umc Core IoC 통합 컨테이너 #1  (0) 2013.05.24
Umc.Core 프레임워크 다이나믹 프록시(Dynamic Proxy) #1  (0) 2013.05.23
Umc.Core 미공개 Preview  (6) 2008.05.14
Umc.Core 란?  (0) 2007.12.01
Posted by 땡초 POWERUMC

댓글을 달아 주세요

필자는 일전에 이와 관련되어 상당한 분량의 포스팅을 올린 적이 있다. 총 5회의 아티클 중 마지막 회를 모두 작성하지는 못했지만, 지금 이 내용이 그 마지막 회의 내용과 어느 정도의 내용과 유사하다고 보면 된다.


그 중, 4회 아티클 ‘[실전 ASP.NET Session [4] - 세션상태 마이그레이션]5’의 내용은 본 아티클의 내용에서 매우 중요한 기초 내용이 된다. 이 글을 읽고 있는 독자 중 잘 이해가 되지 않는다면 필자가 이전에 작성한 포스팅을 반드시 읽어보기를 바란다.

그리고 위의 필자가 작성한 링크의 아티클은 5년전에 작성된 글임을 인지해 주길 바란다. 그 때는 필자가 지금보다도 더 실력이 형편 없었을 뿐더러 현재 추구하는 웹 개발의 트랜드와 상이한 면이 있을 수도 있을 것이다. .NET Framework 버전과 개발툴의 버전도 지금 사용하는 버전과는 한참 예전 버전이었다. 하지만 5년이 지난 글임에도 기초적인 내용은 모두 탄탄하게 짚고 넘어가므로 한번씩 보는 것도 나쁘지 않다.

ASP.NET이 지원하는 분산 세션 상태(Session State)

일반적으로 1대 1의 물리적인 관계는 분명 분산환경이긴 하지만 분산 환경이라고 말하지 않는다. 어떤 물리적인 환경에 배치하든, 통계학의 분산에 대한 기대값이나 편차의 해는 변하지 않기 때문이다.

분산 환경에서 더 나은 성능을 내기 위한 알고리즘과 휘발성인 메모리 안에서 데이터가 유실되지 않도록 원자성(Atomicity)을 유지할 수 있는 방법을 제공해야 한다. 또 웹 서버의 세션이라는 특징은 매우 빈번하게 엑세스 되고, 업데이트와 삭제 작업도 매우 많이 발생한다.

하지만, 안타깝게도 memcached[1]는 ‘get’ 명령의 원자성(Atomicity)를 보장하지 않는다고 한다.

A series of commands is not atomic. If you issue a 'get' against an item, operate on the data, then wish to 'set' it back into memcached, you are not guaranteed to be the only process working on that value. In parallel, you could end up overwriting a value set by something else.


하지만 괜찮다. 웹 서버의 세션은 동시다발적인 병렬 작업으로 요청이 들어올 수 없는 구조이다. 웹 서버로 사용자의 요청이 들어올 때, 사용자의 웹 브라우저에 가진 쿠키 값이 신원보증을 하는 값, 또는 해시된 세션의 키 값이다. 그러므로 한 세션에 대해 동시에 여러 클라이언트(사용자 웹 브라우저)의 요청은 있을 수 없는 일이다.

하지만 불가능한 것도 아니다. 예전에는 자바스크립트가 허용되는 게시판이나 이와 유사한 환경에서 악성 스크립트를 심어 놓으면, 그 글을 보는 누군가는 브라우저의 쿠키 값을 취득하여 해커에게 보내고, 해커는 세션이 만료되는 20분(일반적인 세션 만료 시간) 전에 취득한 세션 값으로 재 요청을 하게 되면 다시 세션이 연장되고, 세션이 로그인된 상태인 경우 해커도 로그인된 상태로 입장하는 것이 가능하다

때문에 완전히 같은 해시된 세션의 키 값으로 여러 클라이언트(사용자의 웹 브라우저)의 요청이 온다는 것은 사용자의 세션 값이 털려서, 누군가 악용하고 있다고 보는 것이 맞다.

그러므로 아주 정상적이고 일반적인 환경에서 원자성을 제공하지 않는 ‘get’ 명령은 전혀 문제가 되지 않으며, 오히려 원자성을 보장할 수 없는 문제로 더 좋은 Read 성능을 낼 수 있기 때문에, memcached 가 세션 서버로 사용하기에 redis[2] 보다 더 좋을 수 있다.

ASP.NET이 제공하는 세션 관리 요약

아무런 설정이 없다면 In-Proc, 즉 로컬 머신의 메모리를 사용하게 된다. 만약 불행히도, Win32 DLL을 참조하는 웹 응용 프로그램이라면 웹 서버의 메모리의 크기 따윈 무시하고 최대 2GB 밖에 사용할 수 없게 된다.

이를 극복하는 방법으로 윈도우 서비스로 백그라운드로 실행되는 ASP.NET Session State Service 서비스를 사용하면 좋다. 여러 웹 응용 프로그램이 하나의 Session State Service에 연결되더라도 웹 응용 프로그램마다 고유의 Identity Key(Guid)가 할당되고, 이를 Primary Key로 구분하게 된다. 이 NT Services가 다운되거나 재시작하지 않는 이상 웹 서버의 세션은 항상 유지할 수 있다.

긴급한 패치로 웹 응용 프로그램을 업데이트 해야 하는 경우, IIS가 재시작 되는 경우가 발생할 수 있는데 이 때 Worker Process에 의해 구동되는 In-Proc 세션 정보는 모두 초기화된다. 웹사이트에서 뭔가를 구매하려는 사용자가 있었다면 큰 사고로 이어질 수 있지만, Session State Service에 세션 정보가 저장이 되므로 IIS 재시작 후에도 웹 응용 프로그램은 세션 정보를 모두 안전하게 유지할 수 있다.

보통 웹 서버와 Session State Service간에 통신을 하기 위해 방화벽의 특정 포트를 개방해야 하고, 내부적으로 서로 간에 소켓 통신에 사용되는 전용 프로토콜이 존재하므로 Session State Service를 확장하기란 쉽지 않을 것이다.

이런 경우, ASP.NET에서 MS SQL Server를 이용하여 세션 정보를 저장하는 방법을 제공해 준다. 세션 정보에 추가하고 싶은 정보나 DB상에 기록되어질 특정 필드를 추가하여 사용할 수 있고, Oracle 또는 MySQL을 사용하여 세션 상태를 저장할 수도 있다.

위의 링크 중 ‘[실전 ASP.NET Session [4] - 세션상태 마이그레이션]13’에 예제로 구현된 Oracle Session Store Provider 예제가 있으니 참고하길 바란다.

memcached를 이용하는 세션 저장소

memcached를 세션 저장소로 이용하는 것은 ASP.NET Session State Services의 역할과 구현만 다를 뿐이지 매우 유사하다. memcached도 메모리를 저장소로 이용하여 빠르게 캐시하고 요청에 빠르게 응답할 수 있는 간결한 구조로 구현된 오픈소스이다.

특히 memcached를 이용할 경우 ASP.NET Session State Services로 불가능한 클러스트링이 가능하기 때문에 수평적으로 세션 서버를 확장할 수 있다. 한 대의 세션 서버만 있는 경우보다 로드벨런싱의 자유도가 더 높고, 세션 서버의 장애에도 대처가 가능하다. 또 하나의 장점이라면 저가형 장비를 병렬로 구성이 가능하기 때문에 세션 서버를 구성하기 위한 금전적이거나 물리적인 많은 제약이 사라지게 된다.

memcached와 redis, 두 가지 오픈소스를 고려하고 있었는데, 세션 서버에 memcached가 더 적합하다고 생각하여 memcached만 다룬다. memcached의 소스 코드가 더 가볍고 취향이나 요구사항에 따라 코드를 변형하기에 더 적합하지 않을까 생각한다. 그리고 자칫 복잡해질 수 있는 구조적인 아키텍처를 좀 더 간결한 memcached로 표현하는 것이 글을 보는 입장이나 쓰는 입장에서 편하다고 믿는다.

memcached는 C언어로 구현이 되어있고, GNU C 표준 라이브러리를 사용하므로 여러 운영체제에서 사용이 가능하다. (ASP.NET Session State Services는 윈도우 환경에서만 사용이 가능하다) 물론 필자는 맥킨토시, 리눅스, 윈도우에서 memcached를 컴파일, 구동이 잘 됨을 확인하였다.

간단하게 사용자의 세션 정보를 저장할 클래스를 하나 간단하게 만들었다. 외부에서는 오직 참조만 하여 사용할 수 있도록 internal 생성 메서드를 하나 가지고 있다.


다음은 ASP.NET MVC 프로젝트로 만든 간단한 예제이다.

web.config
1
2
3
4
5
6
<sessionState mode="Custom" customProvider="MemcachedSessionStateStore">
    <providers>
        <add name="MemcachedSessionStateStore"
             type="Umc.Core.Web.SessionState.Memcached.MemcachedSessionStateStore, Web.SessionState.Memcached, Version=1.0.0.0, PublicKeyToken=eed8f2bc3bfc4c7a, Culture=neutral"/>
    </providers>
</sessionState>

  

HomeController.cs
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
public class HomeController : Controller   
{
   private static readonly string KEY_OF_USER_SESSION = "__USER_SESSION_KEY__";
   public UserIdentity SessionStore
    {
        get { return (Session[KEY_OF_USER_SESSION] as UserIdentity) ?? UserIdentity.Empty; }
        set { Session[KEY_OF_USER_SESSION] = value; }
    }
 
 
    public ActionResult Index()
    {
        Session[KEY_OF_USER_SESSION] = UserIdentity.New("POWERUMC"
                                                        , "Junil, Um"
                                                        , "powerumc at gmail.com");
 
 
         /*
          // 맴버쉽 사용자 인증 설정 생략...
        var ticket = new FormsAuthenticationTicket(...);
        var user = new GenericPrincipal(new FormsIdentity(ticket), ... )
         * */
 
 
        return View();
    }
}

 

위와 같이 클라이언트의 세션 키를 이용하여 memcached의 서버에 세션 키를 이용하여 세션 값을 저장한다.

telnet 'get' 명령 결과
MPOWERUMC:~ powerumc$ telnet 192.168.0.23 11211
Trying 192.168.0.23...
Connected to 192.168.0.23.
Escape character is '^]'.
get laaymm13uyu03bofhdydi4iq
VALUE laaymm13uyu03bofhdydi4iq 0 477
AAEAAAD/////AQAAAAAAAAAMAgAAAF1XZWIuU2Vzc2lvblN0YXRlLk1lbWNhY2hlZCwgVmVyc2lvbj0xLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWVlZDhmMmJjM2JmYzRjN2EFAQAAAEpVbWMuQ29yZS5XZWIuU2Vzc2lvblN0YXRlLk1lbWNhY2hlZC5NZW1jYWNoZWRTZXNzaW9uU3RhdGVTdG9yZStTZXNzaW9uRGF0YQQAAAATPElkPmtfX0JhY2tpbmdGaWVsZBg8TG9ja0FnZT5rX19CYWNraW5nRmllbGQYPEV4ZmlyZXM+a19fQmFja2luZ0ZpZWxkFzxMb2NrSWQ+a19fQmFja2luZ0ZpZWxkAQAAAgwNAgAAAAYDAAAAGGxhYXltbTEzdXl1MDNib2ZoZHlkaTRpcQC8oGUBAAAAAPAWAzAi0IgJAwAAAAs=
END

 

 

ASP.NET의 세션이 실제로 저장이 되었는지 확인해보자. telnet을 통해 memcached 포로토콜의 명령을 입력하여 확인하면 된다.

현재 브라우저에서 연 세션 값은 쿠기에 저장이 되어 있다. 쿠키에 저장된 세션의 키 값은 ‘laaymm13uyu03bofhdydi4iq’ 이다.


telnet에 접속하여 memcached에 저장된 세션 키의 값을 조회된다.

memcached 세션 저장소로써 활용

memcached 오픈 소스 솔루션을 이용하여 메모리 캐시를 이용하여 ASP.NET 세션 상태를 저장할 수 있도록 구성해 보았다. 이제 얼마나 좋은 성능을 낼 수 있는지 측정이 필요한데 본 아티클에서는 memcached를 세션 서버로 활용할 때에 대한 성능의 문제는 다음에 기회가 되면 더 심도있게 다루어 보도록 하겠다.

그리고 ASP.NET 뿐만 아니라, JSP 또는 Servlet, 그 외에 여러 웹 개발 프레임워크에서 쉽게 사용할 수 있다. memcached는 C#, Java, Python 등 여러가지 언어로 memcached서버에 연결할 수 있는 클라이언트 라이브러리를 어렵지 않게 찾을 수 있다.

이번 아티클에서는 MemcachedSessionStoreProvider 소스 코드를 제공하지 않았다. 물론, 필자의 위 코드를 실행하기 위해 MemcachedSessionStoreProvider 소스 코드가 있어야 한다. 이 코드는 다음 아티클에서 조금씩 작성해 나갈 예정이다.

memcached 에 대한 자세한 내용은 아래 링크의 구글 코드에 들어가면 컴파일 및 실행 방법과 유지관리 방법에 대한 위키가 있다.

memcached wiki, https://code.google.com/p/memcached/wiki/NewStart



[1]: C언어로 구현된 고성능 분산 메모리 객체를 캐시하는 서버. Free & open source, high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.

[2]: 키/값을 저장할 수 있는 분산 서버로 데이터의 구조체 뿐만 아니라 문자열, lists, 빠른 검색을 위한 hashes 등을 지원. Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain stringshasheslistssets and sorted sets.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

발생 배경

Qt를 가장 잘 개발할 수 있는 개발 도구 Qt 개발 플랫폼인 Qt 5.0(Qt 5.0 / Qt Creator 2.6.2) 에서 QWebView 위젯을 제대로 link 및 include 할 수 없는 현상이 발생한다. 이전 환경에서는 물론 발생하지 않는, 이전 release에 보고된 버그이다. 

오류 유형은 일치하지 않으나 발생하는 환경은 유사하다고 볼 수 있다. widgets 모듈에 포함되었던 QWebView가 다른 모듈로 분리가 되었기 때문이다. 

:-1: error: symbol(s) not found for architecture x86_64

 

 

해결 방법

해결 방법은 의외로 간단하다. .pro 파일(qmake) 의 속성을 다음과 같이 추가한다.

QT      +=core gui webkitwidgets 


QT 속성은 qmake가 빌드할 때 사용하는 모듈을 지정하는 속성인데, link 또는 dll 개념과 유사하다고 보면 된다. 

그렇다면 정상적으로 다시 컴파일이 가능하고, Code Completion도 정상적으로 동작할 것이다. 아래는 간단한 샘플 소스 코드를 첨부한다.

.pro
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#-------------------------------------------------
#
# Project created by QtCreator 2013-03-11T20:44:09
#
#-------------------------------------------------
QT       += core gui webkitwidgets
 
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
 
TARGET = FacebookNotify
 
TEMPLATE = app
 
SOURCES += main.cpp\
        mainwindow.cpp
 
HEADERS  += mainwindow.h
FORMS    += mainwindow.ui
MainWindow.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QWebView>
  
MainWindow::MainWindow(QWidget*parent): QMainWindow(parent), ui(newUi::MainWindow)
{
    ui->setupUi(this);
  
    this->onLoad();
}
  
MainWindow::~MainWindow()
{
    delete ui;
}
  
voidMainWindow::onLoad()
{
    ui->webView->load(QUrl("http://blog.powerumc.kr"));
}

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 2013.03.24 21:56 Address Modify/Delete Reply

    비밀댓글입니다

  2. knocki 2013.06.14 17:03 Address Modify/Delete Reply

    Qr Creator 2.7.0(32 bit) / Qt 5.0.2 / Windows 7 환경에서는 pro파일에 위의 옵션을 넣어주지 않아도 되네요.

    그런데 프로젝트를 생성할 때 "Qt Gui Application"으로 하면 안 되고 "HTML5 Application"으로 해야만 QWebView를 정상적으로 include하여서 실행이 되네요.

    혹시 두 프로젝트간의 차이점에 대해 아시나요?
    그리고 Qt Gui Application에서는 QWebView를 사용할 수 없을까요?

최신 우분투(Ubuntu) 12.10 64비트 버전을 제 노트북에 설치하였다. 노트북의 해상도는 1600*900로 세로 길어가 짧은 전형적인 와이드형 LCD 모니터이다. 이전 우분투 12.04 LTS에서는 없었던 문제였는데, 이번에는 설치 중 설치 창이 화면을 넘어서서 창이 잘리는 현상이 발생하였다.

   

화면 잘림 현상은 파티션 나누는 단계에서 고급 설정을 선택했을 때 발생한다.

아래의 이미지는 창이 길어져서 항목을 선택하거나 '계속' 버튼을 누를 수 없게 된다. 설치 중 창의 크기를 줄일 수 없기 때문에 이 문제로 조금 난감했다.

이런 현상이 발생하는 경우 창의 타이틀 부분(위쪽)을 ''Alt+마우스 좌 클릭+마우스 이동 ' 하면 두 번째 이미지 처럼 잘린 창 밑 부분을 스크롤 할 수 있다.

[이미지1] 창이 잘린 이미지

   

[이미지2] 창이 잘려 창을 ' Alt+마우스 좌 클릭+마우스 이동 ' 한 이미지

Posted by 땡초 POWERUMC

댓글을 달아 주세요

개요

SpringSource Tool Suite for Eclipse Juno(이하 STS) 를 Eclipse Marketplace 를 통해 설치를 하고자 할 때, Dependencies 체크 후에 아래와 같은 메시지와 함께 설치가 되지 않는다.

Cannot complete the install because one or more required items could not be found. Software being installed: Spring IDE Security Extension (optional) 3.1.0.201210040510-RELEASE
...
...
이하 생략    

이 문제는 인터넷을 통해 필자와 같은 문제의 Thread를 찾을 수 있었다.

  • Thread: cannot install Spring Tool Suite (STS) for Eclipse Juno (3.8 + 4.2) 3.1.0.RELEASE     필자와 같은 문제가 발생하는 경우 위 링크의 답변처럼 GEF(Graphical Editing Framework) 를 설치/업데이트 하면 된다고 한다. 아래의 원문의 링크를 이클립스에서 Help -> Install New Software를 이용하여 설치/업데이트를 할 수 있다. 뭐가 뭔지 잘 모르겠다면 Releases 의 링크를 통해 업데이트하면 된다.

GEF Update-Sites
Using the Eclipse Update Manager (see Eclipse Help for detailed instructions) GEF can be installed from the following update sites:

GEF(Graphical Editing Framework)의 정보는 IBM 사이트에서 찾을 수 있다. 모델링이나 이미지/그래픽 기반으로 Editing 할 수 있는 오픈 소스 프레임워크이다. STS에서 GEF를 이용한 기능적인 향상이나 종속적인 바이너리 등이 변경이 된 듯 싶다.


[이미지 1] GEF Extension 예시 / 이미지 출처 - http://www.eclipse.org/gef/


[이미지 2] Visual Studio DGML / 이미지 출처 - http://msdn.microsoft.com/en-us/library/vstudio/jj739835.aspx  

마치 Visual Studio 의 DGML(Directed Graph Markup Language)과 비슷하게 보인다. 하지만, Eclipse에서의 GEF와 Visual Studio에서의 DGML의 가장 큰 차이점이라고 하면 DGML은 정의된 스키마(Defined Schema)이고, GEF는 확장 가능한 프레임워크라는 점이다. 그 점에서 Eclipse의 GEF에 더 좋은 점수를 주고 싶다..    

GEF와 DGML의 자세한 내용은 아래의 링크를 참고하기 바란다.

Eclipse에서 GEF를 설치/업데이트가 성공하였다면 다시 Eclipse Marketplace에서 STS을 설치한다. 그럼 아래와 같이 못 보던 추가 구성 요소들이 더 많아진다. 그리고 계속 진행하면 설치가 성공할 것이다.    

Posted by 땡초 POWERUMC

댓글을 달아 주세요

개요

Java 8 버전에서 Lambda 표현을 지원한다. 아직 Java 8은 Beta 버전이다. 여러 언어 중에서 Lambda 표현을 지원하지 않는 언어로 손꼽힌다. Wikipedia에서 Anonymous Function을 참고해보면 Java 언어가 언어의 표현력에 있어서 추세를 따라가지 못하는 것이 아닐까 생각한다.

반면,

  • C#은 2007년도에 C# 3.0 버전에 LINQ 라는 대주제를 중심으로 Lambda, Anonymous Class, Extension Methods를 내놓았고,
  • C# 4.0은 2010년도에 Dynamic이라는 대주제를 중심으로 동적 프로그래밍이 가능해졌다.
  • C# 5.0은 2012년도에 비동기 라는 대주제를 중심으로 비동기 프로그래밍을 언어적으로 지원한다.

Wikipedia에서 C# 역사에 대해 더 자세히 알고 싶은 분은 'C# (programming language)' 를 참고하면 좋겠다.

Java를 이용하여 프로그래밍을 하려고 하면 정말 C#이 많이 생각난다. C#에서 한 줄짜리 문장을 Java에서는 십여 줄 넘는 경우가 많기 때문이다. 굳이 예를 들자면, 우리나라에서 유행하는 줄임말 '엄친아'를 풀어서 '엄마 친구의 아들' 로만 말해야 하는 것과 같은 느낌이랄까… 어쨌든 Java는 Java만의 매력이 있는 법. 그 매력을 찾아보는 것도 재미있겠다.

각설하고, 먼저 Java 8을 사용하여 개발할 수 있는 환경부터 간단히 살펴보자.

현재 Java 8 버전은 베타 버전이다. 현재 Java 8은 Sun사의 JDK를 칭한다. 그러므로 Oracle 사이트에서 Java 8 버전을 다운로드 받을 수 없다.

그리고 Project Lambda를 지원하는 개발 툴을 사용해야 한다. 다음의 링크의 NetBeans와 IntelliJ IDEA 12 버전에서 Project Lambda를 사용해볼 수 있다. 아래의 링크에서 다운로드 받을 수 있다.

설치와 JDK 1.8 버전의 환경 구성이 완료되었으면 Lambda 표현을 Java 에서 사용할 수 있다.

Java 8 의 Lambda 샘플 예제 간단한 예제만 소개하겠다.

(Java에서 권장하는 네이밍이나 코드 구현 방식에 맞지 않는 부분이 있더라도 양해 바란다.) 간단한 더하기 계산을 Lambda 표현으로 작성하면 다음과 같다. 



위의 코드로 말미암아 Lambda 표현은 (arguments) -> { … } 로 표현할 수 있겠다.

간단하게 Thread를 돌리는 코드를 Lambda 표현식으로 작성해보자. 




다음은 ExecutorService를 Lambda 표현으로 작성하였다. 





Java의 Lambda 이야기가 나온 김에 어떻게 Lambda 표현으로 발전하였는지도 짤막하게 보자.

원래 이런 코드가 있었다. Runnable Interface를 구현하는 코드이다. 




또는 Java의 Local Class를 이용할 수 있다. Local Class는 메서드 구현부에서 Class를 선언하여 이를 인스턴스화 할 수 있다.

위의 Runnable Interface를 구현한 코드를 Anonymous Class(익명 클래스)로 표현할 수 있게 되었다. 그래서 아래의 예제와 같이 Interface를 구현하는 Class를 만들지 않아도 된다. 



위 Anonymous Class를 Lambda 표현으로 작성하면 더 간결하게 표현할 수 있다. 


단, Java 8의 Lambda 표현에 제약이 있다.

그리고 Project Lambda를 소개하는 페이지의 Functional Interfaces 에서 제약에 대한 설명이 있다. 하지만 이는 근본적으로 Java에서는 C/C++의 Pointer를 표현할 방법이 없는 이유이다. 그러므로 함수를 가리키는 Pointer도 있을 수 없다. 반면, C#에서는 함수포인터를 표현하기 위해 Delegate(대리자)를 지원한다. C#에서는 함수포인터를 안전하게 다룰 수 있다.

그래서 Java에서는 함수포인터를 표현하기 위해서 Listener 형태의 패턴을 주로 사용한다. 다른 말로 Observer 패턴이라고 부른다. Java의 Thread가 대표적이다. Java의 Thread는 Runnable을 인자로 받는 생성자가 있다. 위의 코드에서도 볼 수 있듯이 Runnable은 void run() 메서드만 달랑 가지고 있는 Interface이다. Java의 Thread는 이 Runnable Interface만 알고 있으면 되고, Runnable Interface를 구현하는 인스턴스를 Thread에게 넘겨주면 된다.

반면, C#의 Thread는 Delegate(대리자-안전한 함수 포인터)를 이용하여 Thread를 실행한다. C# 컴파일러는 Delegate를 결국 Class 로 취급한다. 이로 말미암아 Java와 C#에서 포인터라는 것은 언어적으로는 전혀 메커니즘으로 작동하지만 런타임 입장에서는 유사한 메커니즘으로 동작한다는 것을 알 수 있다. 하지만 Java에서 함수포인터를 흉내를 낼 수 있는 방법은 있다. 키/쌍의 컬렉션을 이용하여 참조를 전달하는 방법이다. 아래는 간단한 예제 코드이다. 



어찌되었든 결국, Java의 Lambda는 Interface를 이용하여 Lambda 함수를 만듦으로써 Interface의 함수가 단 1개만 있어야 Lambda 표현을 할 수 있는 제약이 생겼다. Interface를 이용하여 Lambda를 표현한다고 함은 내부적으로 Proxy 객체를 생성하여 그 안에 Lambda 표현을 메서드로 만든다.

아래의 익명 클래스를 보자. 아래의 runnable 로컬 변수를 리플랙션을 이용하여 getMethods() 의 목록이다. 



아래의 Lambda 표현을 보자. 마찬가지로 runnable 로컬 변수를 리플랙션을 이용하여 getMethods() 의 목록이다. 


이를 통해 Java의 Lambda 표현식은 내부적으로 Proxy 클래스가 생성됨이 확인되었다. 그런데 이 Proxy 클래스가 언제 생성이 될까? 컴파일 타임에 생성이 될까, 아니면 런타임에 생성이 될까?

이를 JD-GUI 도구를 이용하여 Decompile 결과를 확인하려고 하였으나, Java 1.8.0 버전에 대해서 JD-GUI 가 올바르게 인식을 하지 못해 전혀 class 파일을 전혀 읽을 수 없다. 대신 .class 파일을 Text Editor 로 열어서 대략적인 내용을 확인할 수 있는데, Text Editor 에서는 Lambda 표현으로 구현된 Proxy Class 를 찾을 수 없었다. 따라서 Lambda 표현은 런타임에 구현 객체 Proxy 가 생성된다는 것을 알 수 있다. (다만, 확신은 못하겠다.)

한가지, Java 8의 Lambda 표현의 다른 점이라면 Lambda 표현의 Proxy 객체는 java.lang.invoke.MagicLambdaImpl 클래스를 상속한다는 점이다. 앞서 얘기했듯이 JD-GUI 도구가 Java JRE 1.8.0 의 rt.jar 파일을 상위 호환성이 아직 지원되지 않아 구현 내용을 알 수는 없었다. 이는 좀 더 Java 8의 Release 시기가 다가오기를 기다려야 할 것 같다. 



결론은 Java 8의 Lambda 표현을 하기 위해서는 Interface 의 구현 함수는 반드시 1개여야 한다는 점이다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 짜두 2013.01.17 08:59 Address Modify/Delete Reply

    이제 베타버전이니 좀더 발전해야 겠네요. 굉장히 빠른 속도로 발전해나가지 않을까하는 생각이 드네요.ㅎ

개요

간단하게 작성한 C++ 코드가 컴파일이 되지 않는다. auto 키워드와 lambda 식을 제대로 해석을 하지 못하는 모양이다.

인터넷을 통해 쉽게 문제를 해결할 수 있었다. 아래의 원문의 링크를 참고하면 된다. 필자는 아래의 링크를 참고하여 스샷좀 뜨고, 예제 샘플 정도만 만들었으니 설정에 어려움이 없다면 아래의 참고 링크만으로 충분할 것이다.

필자가 받은 GCC 4.7.2 버전의 Release 변경 사항을 보면 도움이 될 것이다.

그리고 몇 가지 std 함수 중 to_string 함수에 버그가 있는데, 아직도 Pending 상태라 되도록 사용하지 말고(사용자체가 안된다 ^^;), stringstream 등을 사용하도록 권장한다. SourceForge에서 GCC 버그 항목을 찾아보면 2011년도에 버그가 등록되었지만, 우선순위가 낮아 당분간 고칠 생각이 없는것 같다. (SourceForge GCC to_string 버그 링크)

MinGW-GCC 에서 C++11 컴파일 환경 구성

Project Explorer -> Project Properties -> C/C++ Build 탭 -> Settings 탭 -> Tool Settings 탭 -> Miscellaneous 항목 -> Other Flags 에 -std=c++0x 를 추가한다.

그리고 C/C++ General 탭으로 이동한 후 Paths and Symbols 탭 -> Symbols 탭 -> __GXX_EXPERIMENTAL_CXX0X__ 항목의 Value 값을 0 으로 설정한다.

모두 완료되었다면 Clean Project를 해서 다시 컴파일하자. 아래와 같이 auto 키워드와 lambda 구문에 더 이상 경고와 오류 문구가 뜨지 않고 컴파일도 성공한다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

Qt 개발 환경을 만들려는 참에 Eclipse에서 Visual C++로 만든 프로젝트를 MinGW GCC로 변환해야 할 필요가 생겼다. '인터넷 검색 링크를 잊어버려서… 다시 참고 원문 링크는 찾으려니 찾아지지 않아서... 패스....'

우선 프로젝트를 변환하는 방법은 크게 두 가지가 있는데, 예를 들어, 첫 번째는 전혀 다른 프로젝트를 Dynamic Web Application으로 바꾼다거나… 이런 경우에는 Project Explorer에서 -> Propject Properties -> Project Facet에서 변경하면 된다고 한다.

   

두 번째, 필자가 필요한 것은 이 방법이다. Eclipse에서 Visual C++로 만든 프로젝트를 MinGW로 변경하고자 한다.

Project Explorer -> Project Properties -> C/C++ 탭 -> Tool Chain Editor에서 변경할 수 있다.

   

이제 MinGW GCC 컴파일러를 이용하여 컴파일이 되도록 환경을 수정해야 한다. 이 방법은 아래의 링크를 참고하면 된다.


참고로 필자의 MinGW GCC 환경 변수의 경로이다.

  • INCLUDE - D:\Program Files\MinGW\include
  • LIB/LIBPATH - D:\Program Files\MinGW\lib
  • PATH - D:\Program Files\MinGW\bin

   

여기에서 주의해야 할 것은 Environment 옵션에서 'Append variables to native environment' 항목을 선택한다.

   

Posted by 땡초 POWERUMC

댓글을 달아 주세요

윈도우 8, 요즘 인기가 많다. 일반 사용자들의 후기도 많이 보이고, 더불어 개발자들에게도 기존의 개발 경험을 살려 그래도 개발이 가능해서 인기가 많다. 더불어 C++/CX와 HTML5로 개발이 가능하다.

   

WinRT와 WinMD

그 중에서 C#/XAML을 이용하여 앱을 개발할 경우 Windows 8 Runtime(WinRT)의 라이브러리를 이용하여 개발하게 되는데, 마이크로소프트에서는 이 WinRT를 관리 언어가(Managed 플랫폼 환경) 아닌 C++로 만들어진 네이티브(Native)로 컴파일 되어 있다. 확장된 COM 기반이기 때문에 C#과 HTML5에서 모두 이 라이브러리 APIs 집합을 사용할 수 있다. 이것은 매우 큰 장점이 분명하다.

그런데 말이다. 이 WinRT 자체가 매우 성급하게 만들어진 라이브러리라는 것이 여럿 보인다. 그 중 네이티브로 컴파일된 환경에서 C#과 유사하게 런타임상의 객체나 타입 정보를 알아내기 위해 RTTI(RunTime Type Identification)을 C++/CX 컴파일 시에 자동으로 구현이 된다. 그리고 RTTI를 위해 사용되는 WinRT의 API 정보의 일부는 .WinMD 파일로 저장이 된다. 이를 윈도우 런타임 라이브러리(Windows Runtime Library)라고 하며, 이 라이브러리는 윈도우 8 앱을 개발하는 환경 모두에서 사용할 수 있다.

   

   

   

   

윈도우8 WinRT, XAML의 미완성을 의미하는 IXamlMetadataProvider와 IXamlType 인터페이스

여기에서 문제가 발생한다. 모든 객체들은 C++/CX과 C#에서 XAML(eXtensible Application Markup Language)에서 다룰 수 있다. 그리고 Windows.UI.Xaml 네임스페이스에 XAML과 관련된 APIs 집합이 있다. 그런데 WinRT는 XAML을 핸들링 할 수 있는 라이브러리를 완벽하게 구현해 놓지 못했다.

그래서 WinRT의 IXamlMetadataProviderIXamlType 인터페이스가 생겼다. 이 인터페이스가 WinRT가 XAML을 (꽁수로) 핸들링하기 위해 만들어진 인터페이스로 보인다.

코드에서 새로운 객체를 생성해서 사용하고 싶으면 var obj = new LoginView(); 와 같이 새로운 객체를 생성하는 new 키워드를 사용하면 된다.

객체지향을 완벽하게 표현하는 XAML에서도 마찬가지다. XAML에서 다음처럼 LoginView 객체를 생성할 수 있다.

   

   

여기에서 IXamlMetadataProvider가 미완성 XAML임을 증명해 준다. 윈도우8 모던 앱(Modern App)에서 XAML에서 객체가 생성되는 경우 컴파일 시에 자동으로 생성되는 XamlMetadataProvider.g.cs 파일에서 객체를 생성해 준다. (g는 Generated를 의미한다). 자동으로 생성되는 이 코드는 다음과 같은 코드가 포함이 되어있다.   

   

XAML에서 LoginView 객체 생성을 요청할 경우 IXamlMetadataProvider를 구현한 코드를 통해 객체를 대신 생성한다. 다시 말해, 하드 코딩이 되어있다.   

이는 매우 유감이다. 이는 즉, 런타임상에 동적으로 생성되는 객체나 앱 컴파일 시에 해당 클래스가 포함이 되어 있지 않다면, XAML은 객체를 생성하지 못하게 된다. 동적인 무언가에 의해 생성되는 객체는 XAML에서 명시적으로 객체를 생성할 수 있는 방법이 없어진 것이다. (단, 명시적인 호출)

   

   

사용자가 구현하는 IXamlMetadataProvider

일단 WinRT가 이렇게 구현되어 있으니, 어쩔 수 없다. 동적으로 생성되는 객체에 대해서 XAML에서 명시적으로 객체를 생성하기 위해서는 Custom IXamlMetadataProvider를 구현해 주어야 한다.   

아래는 필자가 개발 중인 Umc.Core.WinRT.dll 에 포함된 Custom IXamlMetadataProvider이다. 윈도우8 모던 앱을 컴파일할 때 MSBuild는 참조되는 어셈블리의 메타데이터를 검색하여 IXamlMetadataProvider 인터페이스를 구현한 객체를 XamlMetadataProvider.g.cs 코드에 자동으로 추가를 해준다. 그리고 컴파일이 된다.

   

   

   

IXamlMetadataProvider가 필요한 경우의 예시

아마 일반적으로 윈도우8 앱을 개발할 때 이 인터페이스를 구현할 필요는 없다. 하지만, 앱을 캡슐화하려고 하고, IoC(Inversion of Control) Container 등을 활용하고자 하고, 동적인 객체가 필요한 경우라면 이 인터페이스를 구현해야 할 필요가 있을 것이다.   


C#이 지원하는 System.Dynamic.ExpandoObject 객체를 생성한다면 이 객체는 XAML에서 명시적으로 호출을 할 수 없다.   

또, System.Dynamic.DynamicObject 를 구현하는 객체도 마찬가지이다. 아래는 Umc.Core.WinRT에 포함된 코드의 일부이다.

   

위와 같은 코드를 이용하여 동적인 객체를 생성하였다면, 명시적으로 구현한 클래스가 없으므로 당연히 XAML에서도 이 객체를 생성할 수 없다.   

이와 같은 경우에 IXamlMetadataProvider를 구현하면 된다.

   


그 밖에 필요한 것들

아마 WinRT는 윈도우폰7 의 API 보다 더 작다. 작은 만큼 없는 것이 많고, 포기해야 하는 것이 많다. 아래에 나열되는 구현체는 http://umcore.codeplex.com 의 필자가 만든 코드를 WinRT용으로 마이그레이션한 것들이다. 조만간 Umc.Core.WinRT도 공개할 것을 약속한다.   

1. WinRT 설계 자체가 IoC Container를 활용하기 매우 너그럽지 못한 구조이다. 그래서 기본적인 WinRT 구조를 많이 벗어난 구조를 직접 구현해야 했다.      


2. MarkupExtension등을 지원하지 않아 Markup 확장이 불가능하여 다른 형태의 XAML답지 못한 요소나 속성들을 따로 만들어야 한다. MarkupExtension등으로 IoC Container 등과 통합을 쉽게 할 수 있으나, 어쩔 수 없이 필자는 Attached Property로 아래와 같이 구현해야 했다.

또는 아래와 같이 LambdaExpression을 이용하여 동적 Compile() 하여 사용하는 형태로 다음과 같이 사용이 가능토록 할 것이다. 이 경우, 위의 방법보다 더 나은 성능을 보여줄 것이다.

 

3. Frame.Navigation은 객체의 Type으로 뷰를 이동한다. 하지만, 하나의 타입에 두 개의 뷰를 만들 수 있는 APIs 를 제공해 주지 않는다 따라서 INavigationService와 NavigationServiceFrame을 직접 구현하여 다음과 같이 하나의 Type 으로 생성되는 뷰는 여러 개의 뷰 객체를 생성할 수 있도록 했다.

다음과 같이 인터페이스를 정의하였고, 기존의 Windows.UI.Xaml.Controls.Frame은 Umc.Core.ModernApp.NavigationServiceFrame으로 대체하도록 하였고, UniquqKey로 구분하여 하나의 Type에 여러 뷰를 생성하여 네비게이션 할 수 있도록 했다.

   

4. IoC Container와 통합된 EventAggregator

뷰에 이벤트를 전달하거나 전역 이벤트를 전달하기 위해서 좀 쉬운 구조로 가기 위해 IoC Container에 EventAggregator를 함께 넣어보았다. Message 방식을 통해 뷰의 이벤트나 전역 이벤트를 구독할 수 있다.

   

그리고 구독을 뷰에서 제어할 수 있도록 하였다.

   

5. IoC Container와 통합된 인젝션. 객체의 인젝션(Injection-주입)은 다음과 같이 이루어진다.

   

6. IoC Container의 Configuration File 구성

이건 이전에 http://umccore.codeplex.com 에 구현해 놓은 것을 WinRT 용으로 마이그레이션 하였다. patterns & practices - Unity의 경우 Configuration을 지원하지 않지만, UmC Core의 IoC는 이를 한번 더 Wrapping 하였기 때문에 구성 파일로 만드는 것이 가능하다.

   

7. IoC Container에서 지원하는 AOP

이는 WinRT 구조상 이를 구현하기가 그리 쉽지는 않다. WinRT에서는 직접 MSIL(MS Intermediate Language)을 이용하여 런타임에 Instructions을 생성할 수 없다. 다만, APIs 가 모자란 만큼 모자란 대로 구현을 할 수 밖에 없다.

예를 들면, C#의 dynamic 을 이용하여 다음과 같이 구현 가능하겠다.

   

   

다음 버전의 윈도우8 앱 SDK 구조는 또 얼마나 바뀔까 걱정!

실버라이트의 일부와 윈도우 폰7에서도 그러하듯 이번 WinRT도 초기 버전이라는 생각이 든다. 생각해보라. 실버라이트 1,2까지 얼마나 개발자의 Needs를 만족해주지 못하였는지. 앞으로 등장할 윈도우 폰8 개발 SDK도 하위 호환성을 일부 포기한다고 알고 있다.   

현재까지 윈도우8 앱 개발 SDK 환경을 본다면, 기존에 가능하던 것들이 WinRT 환경에서 매우 많은 제약이 따른다는 것이 불편하다. 현재 WinRT와 윈도우8 앱 개발 플랫폼의 구조를 본다면, 차기 개발 SDK에서는 WinRT를 얼마나 개선할 수 있을지 알 수는 없다. 아마 WinRT/SDK를 만드신 분들도 참 많이 고민을 했을 것이다.   

다만 WinRT/SDK를 사용하는 개발자에게 그 동안 밟아왔던 원망스러웠던 수순을 밟지 않기를 바랄 뿐이다. 

어쨌든, 윈도우8 WinRT/SDK의 불합리하거나 불편했던 부분을 필자가 구현한 이전에 공개했던 http://umccore.codeplex.com 에 추가로 공개할 예정이다.

'O/S > Windows 8' 카테고리의 다른 글

윈도우 8, 무서운 드라이버와 궁합  (0) 2013.06.05
윈도우 8, 반토막짜리 WinRT와 WinRT SDK  (1) 2012.10.30
Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 김종남 2016.05.15 21:03 Address Modify/Delete Reply

    글 잘 보았습니다.

Windows 8 스타일 개발이 한창 유행이다. 물론 모바일 생태계 전반전인 유행은 아니더라도 Microsoft 기술을 하는 사람들에게는 관심 대상이다. Windows 8 운영체제가 탑재되는 테블릿도 출시가 되고, New iPad 보다 하드웨어 스팩이 좋은 테블릿 출시도 준비중인 곳이 많다고 들었다. 새로운 마켓이 열리는 만큼 테블릿 사용자에게는 새로운 재미를 선사해줄 것은 분명한 사실일 것이다.

Windows 8 스타일 ! 개발을 위해 가지 알아야 구조적인 개념이나 유의사항 정도만 언급하기 위해 글을 나간다. C++/CX, C#,VB XAML(eXtensible Application Markup Language) 이용하여 WPF 데스크탑 응용 프로그램처럼 프로그래밍을 있다. 그리고 HTML/JavaScript 조합으로 개발 환경과 유사하게 개발을 있다. 아마 대부분의 Windows 8 스타일 개발자라면 알고 있는 내용일 것이다. 그리나 포스팅에서는 C++/CX C# 개발 언어를 기준으로 아티클 내용을 채울 것이다.

 

Windows 8 스타일 런타임 관점의 구조

[이미지 링크]

   

WinRT(Windows Runtime) 플랫폼의 구조적 아키텍처 이미지이다. 기존 Windows Desktop 응용 프로그램 환경과 다른점은 WinRT APIs 중간에 끼어있다. WinRT Windows 8 스타일 앱의 핵심이며, Windows 시작하는 Namespace 모두 WinRT 이다.

C#,VB 개발 환경은 그나마 편리한 Library Subset 제공한다. .NET Framework 최소화 버전이라고 보면 된다. 이를 .NET for Windows Store apps 이라고 부르며, 위의 이미지에는 내용이 빠져있다.

C++/CX 잘라 .NET for Windows Stores apps 제공되지 않는다. .NET 개발자라면 System(mscorlib.dll) 으로 시작하는 Namespace 얼마만큼 편한지 알텐데, Library Subset 제공되지 않으니 다른 방법을 사용해야 한다. 쉬운 예로 HttpClient 같은 클래스도 C++/CX MsXml COM 컴포넌트를 이용하는 편이 낫다. 그렇다고 모든 C++ 라이브러리를 사용할 있는 것도 아니다. 이 부분에서 특히 라이브러리의 제한이 있으므로 C:\Program Files (x86)\Windows Kits\8.0\Include\shared 폴더에서 사용가능한 Header 파일을 확인해보도록 하자.

만약 Header 파일의 pragma 선언이 Dektop Family 라면 Windows 8 스타일 앱에서는 사용할 없는 라이브러리이며, 상당한 Header들이 Desktop Family 속하여, 당장 .NET for Windows Stores apps 만큼 쓸만한 클래스들이 없다는 것이 조금 슬프다. 다만, 좋은 소식이라면 C++ boost Library 등이 C++/CX 용으로 컨버전을 시도하는 분들이 많으므로, 조금만 기다려보면 쓸만한 라이브러리들이 대거 출연할 것으로 보인다.

   

더불어 C#, C++ 개발자들도 알고 있어야 하는 중에 하나가 WinRT COM 컴포넌트 기반의 라이브러리라는 것쯤은 들어보았을 것이다. 그래서 Windows 8 스타일 개발자들은 COM 대한 개념과 나아가 이를 구현할 있다면 좋다. 특히 C#, VB 에서 WinRT 컴포넌트를 만드는 것은 가지 지켜야할 제약이 있으므로 다음의 링크를 참고하는 것이 좋다.

C# Visual Basic으로 Windows Runtime 구성 요소 만들기 http://msdn.microsoft.com/ko-kr/library/windows/apps/br230301.aspx

   

대신 C++/CX WinRT 컴포넌트를 만드는 것이 오히려 간단하다. 앞서 말했다시피 WinRT COM 컴포넌트 기반이지만, 기존 C++ 에서 COM 컴포넌트를 만드는 만큼 어렵지가 않다. C++ COM 구현의 첫번째는 IUnknown 인터페이스를 구현하는 것이지만, WinRT 에서는 Iunknown을 상속하는 IInspectable 인터페이스가 더 중요하다. IInspectable 인터페이스는 C++/CX 개발된 응용 프로그램이 런타임 해당 클래스의 정보를 제공하기 위한 인터페이스이다. 물론 기존 C++ 에서도 런타임상 클래스 정보가 필요하여 이를 직접 구현하는 방법도 있다. 하지만 C++/CX IInspectable 인터페이스는 C++/CX 컴파일 과정에서 자동으로 구현을 해준다. 이는 IUnknown 인터페이스까지 자동으로 구현해준다고 보면 된다. 그렇기 때문에 Iunknown 인터페이스의 AddRef, Release 메서드에 대한 객체 수명주기를 WeakReference 클래스를 통해 위임할 있다. WeakReference 통해 금방 해제될 있는 컴포넌트를 가비지 컬렉터 대상이 되도록 지정한다. 그러므로 사용 빈도가 매우 많고, 매번 자원 해제에 대한 비용이 반복되는 것은 WeakReference 효과적으로 객체 수명 주기를 다룰 있게 한다. 이러한 C++/CX 특별히 제공되는 라이브러리는 Microsoft.WRL Namespace 포함되어 있다.

아직 이러한 개념적인 부분이 어렵게 느껴진다면 월간 마이크로소프트 5월호 특집 기사로 기고한 필자의 다음의 글부터 참고 바란다.

[월간 마이크로소프트 5월호 특집기사] C++ 매트로 개발을 위한 C++/CX 언어 http://blog.powerumc.kr/378

   

   

Windows 8 스타일 응용 프로그램 관점

짧게 말해 Windows 8 스타일 개발은 쉽다. Visual Studio 2012에서 훌륭하게 대부분이 구현된 템플릿을 제공하기 때문에, 메서드 중간 중간 원하는 기능을 추가하고, 클래스나 XAML 만들면 된다. 다만, 이는 만든다는 것이 쉽다는 것이지 응용 프로그램 구조적인 측면에서는 전혀 쉽지 않다.

먼저 알아야 것이, Windows 8 스타일 페이지를 상태 관리 것인지, 것인지부터 결정해야 한다. 상태 관리를 유지할 필요가 없다는 것은 개발(ASP.NET/ASP/PHP/JSP) 같은 서버 사이드 개발 환경과 유사하다. 특히 IIS에서부터 ASP.NET까지 연결되는 Application Pipeline 매번의 Request마다 Pooling Thread 활성화되어 서버 랜더링을 통해 사용자에게 HTML Response 전달이 된다.

   

1. 상태 관리를 개별적으로 유지하고 싶다면

다음의 가지 메서드를 재정의하면 된다. ASP.NET Custom Control 구현해 보았다면 VIEWSTATE 상태 유지를 위해 이런 유사한 코드를 구현해야 하는 것을 것이다.

   

Frame.Navigate 메서드는 Page Type 인자로 받고, 매번 새로운 인스턴스를 생성한다. (구현을 다르게 한다면 인스턴스를 이용하도록 수도 있다.) 페이지의 상태 유지야 위의 메서드를 재정의하는 정도로 끝낼 있지만, 페이지에 포함된 UserControl 있다면 상황은 달라진다. 독자마다 구현하는 방법은 다르겠지만, 효과적으로 상태를 관리하기 위해 UserControl 조금 귀찮아지는 존재이다. 인스턴스의 재사용을 위해 자주 사용하는 UserControl 대한 상태 관리를 고민해야 하다니… (현재 아티클은 내용이 대해 오픈 소스 제공으로 효과적인 방법을 제안하도록 필자는 약속 하겠다.)

   

2. 상태 관리를 자동으로 캐싱하고 싶다면

상태 관리를 자동으로 캐싱하는 방법도 매우 쉽다. Page.NavigationCacheMode 프로퍼티를 Enabled 해주면 된다. 물론 XAML 코드에 속성을 추가해도 된다. 하지만 아쉽게도 Frame.Navigate 메서드를 통해 자동으로 상태 관리를 하도록 Page 새로운 인스턴스가 생성이 된다. 상태 관리 캐싱에 대한 조건은 GoBack(), GoFoward() 같은 Frame 이동에 대해서만 유효하다. 조금 이해할 없는 부분은 Page 포함된 UserControl 상태 관리 캐싱 대상에서 제외된다. (물론, 가능하도록 있지만 개념적으로 깊게 이해하고 구현해야 한다.)

   

3. 남발되는 async/await 의한 동기화 문제

Windows 8 스타일 앱을 사용하다가 자주 멈짓 멈짓 한다면 분명 사용자는 짜증날 것이다. 때문에 async / await 키워드를 더욱 자주 사용하는 편이다. 그렇기 때문에 UI 상태에 대한 비동기와 컴포넌트나 인스턴스 메서드 호출에 대한 비동기, 모두 정확하게 Threading 대한 지식이 필요하고, 자유 자재로 Threading 다룰 있다면 더욱 좋다. Windows 8 스타일 앱에서 가장 많이 발생하는 Threading 문제는 Thread 실행 인스턴스 해제에 대한 동기화와 Thread Cancel 대한 동기화다.

문제를 피하기 위해서는 클래스나 라이브러리를 만들때 부터 async / await 대한 고려가 필요하다. 쉽게 이야기하자면 자주 쓰지 않는 편이 좋고, 써야 곳에 써야 한다.

   

이를 판단하려면 Thread 동기화에 대해 적어도 가지는 반드시 익히는 것이 좋다. MSDN 아래의 글들을 번정도 필독하기 바란다.

관리되는 스레딩 기본 사항 http://msdn.microsoft.com/ko-kr/library/hyz69czz
스레딩(C# Visual Basic) http://msdn.microsoft.com/ko-kr/library/ms173178(v=vs.110)

   

      

Windows 8 스타일 배포와 라이브러리 배포 문제

부분은 매우 민감한 부분이고 조심스럽다. 실제 Windows App Store에서 테스트할 없을 뿐더러 개발 환경에서 발생하는 문제이므로, 실제 Windows App Store 통해 발생할 수도 있을 가능성이 있을 같다. COM 기반 라이브러리나 DLL 구성 요소 등은 공유 메모리에 로드가 된다는 것을 것이다. 특히 부분은 COM 컴포넌트에서 민감하게 다루는 IUnknown 인터페이스의 의미와 일맥 상통한다. , COM 객체의 참조 카운트(Reference Cout) 0 되지 않으면, 자원은 해제되지 않는다. 여기에서 COM 가장 고질적인 문제가 발생한다. 바로 DLL 지옥이다. Windows 8 스타일 앱의 메모리 위치는 메모리 영역이 아닌 공유되는 메모리 영역에 위치하고 있고, DLL Verserning 자유롭지 못하다. .NET 처럼 GAC(Global Assembly Cache)에서 DLL 버전별로 관리되지 않는다.

따라서, WinRT 런타임 라이브러리를 개발하여 배포된 Windows 8 앱이 활성화 상태일 새로운 앱에서 버전업 WinRT 런타임 라이브러리 배포시에 다른 프로세스가 점유하고 있다는 오류가 발생한다. 이는 앱이 초절전 유휴 상태에 진입되어도 마찬가지이다.

이찌되었든 개발 환경에서는 충분히 발생된 문제이니, 차후 Windows App Store에서도 발생할지는 지켜보아야 것이다.

   

Windows 8 Windows Runtime 재배포 정책 업데이트

런타임 라이브러리인 만큼 라이브러리 코드가 완벽하지는 않을 것이다. .NET Framework 1.0부터 4.5까지 버전업이 되어왔는데 과연 Windows 8 Windows Runtime 어떻게 버전업이 될까? 사용자의 동의 없이 업데이트나 패치는 불가능하다.

   

Windows 8 Features Pack 1,2,3… 시리즈로 업데이트가 될까?
Windows 8 Service Pack 1,2,3… 시리즈로 업데이트가 될까?

   

만약 이렇게 되면, Windows 8 스타일 간에 호환성 문제가 발생할 것이 분명하다. Apple iPhone 모바일 폰의 운영체제 업데이트가 실시간으로, 온라인으로 이루어진다. Windows 8 iPhone 업데이트와 차원이 달라진다. WinRT 지원하는 ARM 버전과 기존의 Windows 8 Desktop 지원하는 x86 버전 가지의 에디션이 있다.

혹시 부분에 대해서 알고 있는 정보가 있으면 공유 부탁 드립니다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

윈도우 8, 뜨거운 감자 [1/2]-무엇이 사용자를 화나게 하는가?
윈도우 8, 뜨거운 감자 [2/2]-혁신은 언제나 리스크를 안고 간다


 필자는 마이크로소프트의 윈도우 8 전략을 조금은 이해한다고 생각한다. 물론 다른 사람들이 볼 때 자신의 의견과 다르거나 필자가 어느 한 쪽으로 편향이 되어 보일 수 있겠다. 하지만, 필자는 진정으로 마이크로소프트의 소프트웨어들을 사랑한다. 필자는 리눅스를 초보이기 때문에 리눅스에 대한 어떠한 피드백을 줄 것도 없거니와 큰 불만도 없다. 리눅스 커널을 뿌리깊게 공부해 본적도 없고 리눅스 전용 소프트웨어를 개발해 본적도 없다. 윈도우 8이라는 뜨거운 감자에 대해 이런 글을 쓰는 것은 그 만큼 윈도우 운영체제를 아낀다는 반증이라고 생각해 주기 바란다.

윈도우 8은 새로운 혁신이다. 일단 현재의 불편함은 윈도우 8 RTM 출시 후 냉정한 사용자의 평가에 맡길 수 밖에 없으므로 이야기를 전환해 보자. 윈도우 8은 우리에게 무슨 메시지를 전하고 싶어하는가?

   

윈도우 8 운영체제가 곧 클라우드이며, 운영체제의 상식의 한계점을 넘었다.

운영체제(OS-Operating System)는 알다시피 '하드웨어와 사용자를 연결'하는 가장 추상화된 레벨이다. 그리고 지금까지의 윈도우 운영체제는 운영체제의 본연의 역할에 충실했다. 하지만, 이제는 윈도우 8 운영체제는 SaaS(Software as a Services)와 통합이 되었다. 운영체제가 SaaS와 통합하기 위해 운영체제는 인터넷이라는 거대한 네트워크와 베플(Best Friend)이 되어야 한다. 최종 사용자에게 소프트웨어를 위한 어떤 서비스를 제공하기 위해 인터넷이라는 매개체를 이용해야 한다. 이로써 운영체제는 운영체제의 기본 역할을 넘어 고객의 요구와 눈높이에 맞추는 소프트웨어 서비스를 제공하는 서비스 프로바이더(Services Provider)가 되었다.

 

   

아마 윈도우 8 운영체제 덕분에 언젠가는 운영체제(OS)의 의미가 더 큰 의미로 사전에 추가될 것이다. '운영체제란? 하드웨어와 소프트웨어, 인터넷을 아울러 최종 사용자에게 가치 창조형 서비스를 제공하는 소프트웨어' 라고 말이다.

   

윈도우 8, 하이브리드 N 스크린

하이브리드 N 스크린. 필자가 이렇게 이름을 지어보았다. N 스크린의 의미는 '폐쇄적인 1~2~3 스크린을 확장하여 N개의 디바이스, N개의 스크린, 그리고 개방형 서비스' 라고 정의할 수 있다. N 스크린을 실현하기 위해 플랫폼의 구축이 반드시 필요하였다. 왜냐하면 N 스크린의 개방형 서비스를 실현하기 위해서는 클라우드라는 규모있는 대규모 플랫폼으로 PaaS(Platform as a Services), IaaS(Infra as a Service), SaaS(Software as a Services)가 제공하는 서비스가 N 스크린의 서비스 품질을 결정한다고 해도 과언이 아니다. 

예를 들어, 일부 2세대 휴대폰이나 최신 스마트폰에서 제공하는 DMB로 TV를 시청하는 서비스를 상상해보자. DMB 전파를 위해 별도 채널을 확보해야 하고, 기존의 기지국에서 DMB 전파를 송신할 수 있는 장치 등이 필요할 수 있다. 혹여 위성 DMB 서비스를 이용하려면 서비스 제공자는 위성이 필요하다는 것이다. DMB 시청에 필요한 모든 서비스를 하나의 플랫폼으로 구축되어 있다고 이해해도 될 것 같다.

 

   

다시 이야기의 원점으로 돌아가서, 필자가 지적한 윈도우 8 의 불편한 것 중의 하나가 '시작' 버튼이 없어진 것이다. 이것을 상징적인 의미로 바꾸어 표현하면 윈도우 8은 더 이상 데스크탑 전용 운영체제가 아니며, 데스크탑이 메인이 아니라는 것이다. 그렇다고 윈도우 8이 테블릿이나 모바일을 메인으로 하는 운영체제도 아니다. 필자가 이름지어 본 '하이브리드 N 스크린'을 기억하는가. 상상해 보자. 윈도우 8 운영체제는 N 명의 사람들이 어깨동무를 하고 동그랗게 모여있는 모습을 하늘에서 내려다본 그 모습이 윈도우 8의 모습이다. 

윈도우 8을 현재의 모습보다 미래지향적으로 바라본다면 매우 파괴력 있는 운영체제임은 틀림이 없다. 대신, 그 리스크(Risks)도 안고 가야 하는 것도 윈도우 8의 운명이다. 미래를 향한 파괴력인지, 스스로 자멸하는 파괴력인지 마이크로소프트의 몫이라고 할 수 있겠다. 그렇기 때문에 마이크로소프트의 윈도우 8은 전세계의 윈도우 사용자와 함께 어깨동무를 하고 나아가야 할 소셜틱한 운영체제임이 틀림이 없다.

   

   

윈도우 8, 그리고 …

필자가 윈도우 8에 대해 볼멘 소리를 하다 말고 윈도우 8의 미래지향적인 메시지를 얘기하는 것도 매우 재미있다고 느껴진다. 필자는 윈도우 8의 양날의 검이라고 생각한다. 마이크로소프트가 수 많은 사용자의 피드백을 무시하고 내놓은 윈도우 8 운영체제에 대해 냉혹한 평가를 받아야 한다.

그리고 윈도우 8이라는 뜨거운 감자는 쉽게 식지 않을 것 같다. 이제는 마이크로소프트의 몫이다. 맛있게 속이 알차게 익은 감자가 될지, 다 타버리고 재만 남는 감자가 될지는 아직 아무도 섣불리 판단하기 이르다. 다만, 우리 사용자 입장에서는 윈도우 8 이 발전하고 좋아져야 하는 것은 당연한 것이다. 사용자가 싫어하는 것을 하지 않거나 보완하는 것이 진정으로 위하는 것이라는 모 기업의 TV 기업 이미지 광고의 의미도 곱씹어 보아야 할 것이다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 개발자 2012.08.20 14:18 Address Modify/Delete Reply

    잘 봤습니다. MS 를 사랑하는 개발자로서 공감이 가네요. 빌 돌아와줘요~~~

  2. 지나가는이 2012.08.21 22:09 Address Modify/Delete Reply

    마우스 오른쪽 클릭하면 시작버튼 누를때 나오는 것과 비슷한 것이 뜹니다.
    이전보다 기본적으로 필요한 것들이 들어가 있고 더 좋은데요..
    사용해 보면 windows8 굉장히 유용합니다.
    과거에는 안티였지만 windows8로 그나마 변하느낙 부다 좋은징조로 받아들이는데.
    mvc분들은 과거에는 이해할수 없이 찬양하더니 windows8 나오니 비판적이신듯..ㅋㅋ

    • NikooRn 2012.11.27 10:51 Address Modify/Delete

      문제는 오른쪽 클릭을 해도 윈도우7에서 하던 많은 것들이 안되는게 문제죠.. 특히 시작화면의 앱에서는 오른쪽 클릭을 해도 앱에서 다양하게 이루어지던 기능들이 많이 빠져있고 계정도 일반계정이라 힘드네요...

  3. çatı 2012.08.31 02:46 Address Modify/Delete Reply

    아주 좋아요. 감사

윈도우 8, 뜨거운 감자 [1/2]-무엇이 사용자를 화나게 하는가?
윈도우 8, 뜨거운 감자 [2/2]-혁신은 언제나 리스크를 안고 간다


윈도우 8, 마이크로소프트의 가장 최신 버전의 운영체제이다. 2009년 10월 23일, 윈도우 비스타의 부진을 딛고 윈도우 7을 출시하였고, 이는 현재까지도 마이크로소프트의 성공한 운영체제로 평가 받고 있다. 특히 윈도우 7은 윈도우 비스타에 비해 월등히 빠른 성능과 글래스 스타일(Glass Style) 효과인 반투명한 윈도우 창이 윈도우 운영체제에 매우 조화롭게 녹아 들었다. 필자 또한 윈도우 XP 이후 가장 오랫동안 사용한 운영체제가 바로 윈도우 7이기도 하다.

 

   

(본 아티클에서는 어휘의 자연스러움을 위해 용어는 영문 또는 한글을 혼합하여 사용하였음을 양해 바란다. 그리고 '메트로 스타일' 용어에 대해 마이크로소프트의 공식적인 지침이 없으므로 '메트로 스타일'과 '윈도우 8 스타일' 등의 용어를 혼용하여 사용한다.)

   

윈도우 8을 논하기 전, 윈도우 비스타와 윈도우 7부터...

윈도우 비스타와 윈도우 7, 무엇 때문에 운영체제의 성패를 좌우하였는가? 사용자에게 보여지는 글래스 스타일의 UI 효과도 똑같았고, 사용자 계정 컨트롤(UAC, User Account Control)의 강력한 사용자 측면의 보안 강화와 같은 기능들은 대부분이 유사하였다. 특히 외관상 전문가가 아니면 구분하지 못할 정도로 두 운영체제 모두 아름다운 사용자 인터페이스를 가졌다.

 

   

그렇다면 무엇이 윈도우 비스타를 추락시켰나? 큰 맥락만 짚고 넘어가보자. (단, 개발 입장에서는 더 큰 어려움이 많았지만, 이 아티클에서는 주요한 사용자 측면만 요약한다)

  • 첫 번째로 운영체제의 하위 호환성이다. 게임 유저들이 게임을 하기 위해, 그리고 윈도우 응용 프로그램 또한 기업용 응용 프로그램들이 윈도우 XP 사용을 유지하였거나 윈도우 XP로 다운그레이드를 하였다. 그 이유는 하위 호환성이 완벽하게 보장이 되지 않았으며 보안 프로그램(특히 기업용)이나 시스템 레벨에서 동작하는 소프트웨어(드라이버 등)의 마이크로소프트 파트너에서도 이에 발 빠르게 대응하지 않은 문제도 있었다.
  • 두 번째, 운영체제 성능이다. 사용자가 운영체제를 사용하기 위해 다양한 동작을 하게 되는데, 그 중에서 응용 프로그램을 실행하고, 인터넷을 즐기기 위해 브라우저를 실행하고, 사용자가 체감적으로 느끼는 반응 속도가 윈도우 XP에 비해 성능이 현저하게 떨어졌다. (응용 프로그램 버전, 브라우저 버전에 대한 성능 문제는 이 아티클에서는 논외로 한다)
  • 세 번째, 사용자를 괴롭히는 사용자 계정 컨트롤(UAC). 윈도우 XP에서는 대부분 사용자 계정을 최고 관리자 계정(Administrators) 범주에 포함이 되었으나, 윈도우 7에서는 사용자 계정은 관리자 계정이 아닌 일반 계정이다. 그래서 응용 프로그램 등이 사용자 시스템의 리소스에 접근하기 위해 사용자에게 허가를 받아 임시로 계정 권한을 관리자로 승격시키는 것이 주요 컨셉트이다. 이로써 악성코드나 바이러스는 자기은폐나 자기복제를 하기 위해 사용자 시스템의 리소스에 접근할 수 있는 권한이 근본적으로 차단이 되었다. 하지만, 이런 권한 승격을 위해 사용자에게 묻는 횟수가 너무하다 싶을 정도로 많았기 때문에 사용자에게 분노를 느끼게 할 정도였다.

   

그렇다면, 왜 윈도우 7이 성공했는지에 대한 대답은 간단하다. 위의 세 가지의 문제들이 모두 깔끔하게 해결되었기 때문에, 더 이상 사용자는 윈도우 XP에 머물 이유가 없었다. 윈도우 7의 보안 향상이라는 점 때문에 기업에서도 적극적으로 관심을 보이며, 국내 굴지의 대기업에서 전사적으로, 일부는 점진적으로 직원들이 사용하는 컴퓨터의 운영체제를 윈도우 XP에서 윈도우 7으로 업그레이드를 하였다. (즉, 윈도우 비스타는 건너 뛰었다) 필자가 다니던 전 회사인 N모 게임사도 2011년 3000여명의 전사적 차원에서 윈도우 7으로 교체하였고, 운영체제의 표준으로 자리잡았다.

   

   

윈도우 8, 윈도우 비스타를 방불케 하는 뜨거운 감자!

이 아티클을 쓰는 시점, 윈도우 8은 이미 제조사에게 제공되는 RTM 버전이 공급이 되었다. 윈도우 8이 공식적으로 출시가 되면 많은 제조사에서 생산되는 데스크탑 컴퓨터, 노트북, 울트라북, 테블릿 기기에 윈도우 8이 기본 탑재가 되어 출시될 것이다.

   



무엇이 윈도우 8을 뜨거운 감자로 만들었는가?

(단, 이 아티클에서는 윈도우 8을 데스크탑 운영체제 관점에서 바라볼 것이며, 테블렛은 특별히 언급하지 않는 한 논외로 한다.)

   

  • 시작 버튼
    윈도우 8에는 '시작' 버튼이 사라졌다. 별것도 아닌 '시작' 버튼이 무엇이 문제가 되는지 잠시 되짚어보자. 마이크로소프트는 윈도우 운영체제가 부팅되면 '바탕화면'이 사용자에게 가장 먼저 보이는 UI이다. 최초 이 텅 빈 UI에 사용자는 윈도우라는 운영체제를 배우지도 않아도 사용할 수 있는 방법이 필요했고, 그 획기적인 방법이 '시작' 버튼이다. 10년이 훨씬 넘는 긴 세월 동안 윈도우는 '시작' 버튼으로 사용자가 사용하기 쉬운 운영체제가 되었다.
    10년도 더 이전에는 '시작' 버튼이라는 용어 자체가 획기적이었다. 당시의 대부분의 소프트웨어는 각 기능의 접근을 위해 '메뉴'라는 것을 구현하였다. 기술적으로 이 메뉴 구현을 '풀다운 메뉴(Pull-Down Menu)' 라는 기법을 사용하였고 이 기법은 2진-트리와 비슷한 자료구조의 형태이다. '풀다운 메뉴' 단어에서 알 수 있듯이 최상위 메뉴가 하위 서브 셋 메뉴를 갖는 획기적인 방법이었다. 모든 소프트웨어들은 GUI(Graphics User Interface)의 유무에 상관없이 함께 필수적으로 구현하는 것이 '풀다운 메뉴'였다. 윈도우에서 '시작' 버튼은 단순히 메뉴라는 기능적인 관점을 넘어 사용자의 경험(UX)에 즉각적으로 향상된 사용자 경험을 제공해 주었다. '시작' 버튼의 기능은 단순히 메뉴가 펼쳐지는 UI에서 점차적으로 많은 개선이 이루어졌고, 현재의 윈도우 7의 모습으로 발전한 획기적인 바로 그것이 '시작' 버튼이다.



    윈도우 8의 '시작' 버튼이 사라지는 것에 대해 많은 찬반 토론이 있지만, '시작' 버튼의 그 기원 자체를 인정하고 시작해야 한다. 그깟 '시작' 버튼이 윈도우를 대표하고 윈도우라는 운영체제를 연상케 하는 핵심적인 요소임이 분명하다는 것을 인정해야 한다. 그렇지 않으면 '시작' 버튼의 유무에 대한 논의 자체가 불필요하다. 최근 '시작' 기능 자체가 매우 많은 기능을 담당하고 사용 방법도 복잡해짐에 따라 '시작' 버튼에 대한 혁신이 필요하다는 관점에서 '시작' 버튼이 없어지는 것을 환영하는 사람도 있다. 반면, 필자와 같이 '시작' 버튼이 반드시 필요하다는 사람들은 '시작' 버튼이 사라지는 것을 상당히 우려하고 있고, 가장 큰 불만 중 하나이다. '시작' 버튼이야말로 윈도우의 기능과 소프트웨어 자원의 집합체를 바로 '시작' 버튼에 모든 것을 담아낸 최고의 사용자 경험이었다.
    초기 버전의 윈도우 8 CTP(Consumer Preview와 상응 또는 그 전후) 버전에는 레지스트리를 통해 '시작' 버튼을 활성/비활성 할 수 있는 방법이라도 제공이 되었지만, 윈도우 8 RTM 버전에는 이 방법마저도 제공해주지 않는다.

    즉, '시작' 버튼이 사라진 것을 받아들여야 한다. 이로써 사용자 관점에서 기존 통합된 UX가 분산되어 버렸다. 과연 '시작' 버튼을 제거한 것이 향상된 사용자 경험인지에 대해서는 추후에 냉철한 평가가 필요할 것이다.
    • 시작 버튼의 모든 프로그램 항목들은 메트로 시작화면으로...
    • 시작 버튼의 제어판과 컴퓨터 관리는 바탕화면에서 제스처를 통해 슬라이드 메뉴를 활성화시키는 것으로...
    • 시작 버튼의 시스템 종료도 제스처를 통한 슬라이드 메뉴를 활성화시키는 것으로 ...
    • 시작 버튼의 윈도우 내의 자원의 검색은 매트로 시작 화면의 검색 기능으로...
    • 키보드의 Windows 키는 '시작' 버튼의 시작 메뉴 활성화 기능에서 매트로 시작화면<->데스크탑 바탕화면 전환으로…

    결국 '시작' 버튼을 제거하여 '시작' 버튼이 제공하는 기능을 분산시켜 버렸기 때문에, 클릭 1~2번으로 해결할 수 있는 것들을 클릭+제스처를 이용하여 좀 더 어려운 동선을 그려야 한다. 그리고 사용자들이 '시작'만 보고도 윈도우를 쉽게 사용할 수 있었지만, 윈도우 8 사용자는 무엇을 보고 '시작'해야 할까?

       


   

메트로 스타일 (윈도우8 스타일 사용자 인터페이스 및 사용자 경험)

마이크로소프트가 정식으로 '메트로(Metro)'라는 단어를 사용한 것이 윈도우 폰 7에서 시작되었다. 필자는 이 메트로 스타일의 UI를 보았을 때 감탄을 하였다. 전혀 마이크로소프트의 발상이라고 할 수 없을 정도로 퀄리티가 높은 사용자 인터페이스였다. 마이크로소프트가 출시하는 대부분의 소프트웨어들은 전형적인 마이크로소프트 스타일의 '콘솔(Console)' 형태의 사용자 인터페이스이다. 수십년 동안 '콘솔' 화면에 익숙해진 것인지 메트로 스타일의 사용자 인터페이스는 그야말로 획기적일 보일 수 밖에 없었다.
윈도우 폰 7이 다른 국가에 비해 국내 출시가 매우 늦어진 탓인지 메트로 UI에 대해 이런저런 불만의 목소리는 거의 없었다. 하지만, 윈도우 폰 7은 국내 출시되고 얼마 되지 않아 상당한 불만들이 쏟아져 나오기 시작했다. 폴더 기능의 부재는 윈도우 폰 7의 불만 중에 하나이다. 그 흔한 모바일 운영체제에서 지원하는 폴더 기능을 제공하지 않는다. 수 많은 앱들 중에 비슷한 앱을 묶어 폴더에 담기도 하고, 자주 사용하는 기능을 폴더링하여 접근성이 좋은 첫 페이지에 놓기도 한다. 하지만, 당연하다고 생각하는 폴더 기능조차 윈도우 폰 7에서는 제공되지 않는다.

   

폴더 기능의 부재 때문에, 윈도우 폰 7에서는 앱이 많아질수록 앱 관리가 힘들어졌다. 앱을 찾기 위해 무한 스크롤을 해야 하고, 어느 앱이 어느 앱인지 분간하기도 쉽지 않다. 아이콘으로 앱을 구분할 수 없고, 수 많은 네모 칸의 이 색깔 ,아니면 저 색깔의 앱들을 무슨 수로 빠르게 찾을 수 있었겠는가. (필자는 검색 기능을 말하는 것이 아닌, 육안으로 인식하는 것에 대한 것임을 유의하기 바란다)

 

   

이미 윈도우 폰 7의 메트로 스타일의 폴더 기능의 부재로 겪게 되는 불편함은 여전히 윈도우 8에서 개선되지 않았다. 정말 필자가 느끼는 것 중의 가장 불편한 것이라면 첫 째도 폴더 기능이고, 둘 째도 폴더 기능이다. 윈도우 8의 메트로 바탕 화면에서 단색의 네모 칸의 앱 아이콘은 도저히 앱들을 분간할 수 없을 지경이다. 그나마 검색 모드로 전환해야 같은 분류의 앱들이 어느 카테고리인지 표시는 해주지만 사실 눈에 잘 띄지도 않는다. 그리고 원하는 곳으로 이동할 수도 없기 때문에 사실상 더 불편해 졌다고 느껴진다.

   

데스크탑 응용 프로그램을 찾으려면 메트로 바탕화면으로 가야 한다.

필자의 입장에서 가장 이해가 되지 않는 부분이다. 왜 데스크탑 응용 프로그램을 실행하기 위해 메트로 바탕화면으로 이동해야 하는가. 윈도우 8에서는 데스크탑 응용 프로그램을 찾기 위해서 메트로 바탕화면으로 이동해야 한다. 그리고 데스크탑 응용 프로그램 아이콘을 클릭하면 다시 데스크탑 바탕화면으로 이동하고 응용 프로그램이 실행된다. 예를 들자면, 필자가 게임을 실행하기 위해서 '메트로 바탕화면 이동 -> 게임 응용 프로그램을 스크롤하며 찾기 -> 게임 응용 프로그램 클릭 -> 데스크탑 바탕화면으로 강제 전환됨 -> 게임 실행됨'. 몇 달 동안 윈도우 8을 사용해왔지만 여전히 비효율적인 방법이라고 느끼며 불편하다.

   

 

데스크탑 응용 프로그램은 데스크탑에서 찾고... 메트로 앱은 메트로 바탕화면에서 찾아야 한다. 하지만 윈도우 8은 모든 응용 프로그램과 앱들을 메트로 바탕화면에 몰아 넣었다. 필자는 노트북 또는 데스크탑을 사용할 때 메트로 앱을 사용할 일이 없고, 메트로 바탕화면으로 가야 할 일도 없다. (물론 사용자마다 틀리겠지만...). 필자는 메트로 앱 중 뉴스 앱보다 데스크탑에서 브라우저로 뉴스를 보는 것이 빠르고 편하다. 더불어 체감적으로 브라우저 랜더링에 비해 메트로 앱의 랜더링은 너무 느리다. 필자가 사용하는 데스크탑 경험은 바로 이것이다. 즉, 데스크탑 경험에서는 메트로 시작 화면이 필요 없다. 물론, 재미있는 메트로 게임 앱이 나온다면 기분 전환 삼에 사용할 의향도 있다. 하지만 필자의 데스크탑 경험에서는 메트로 시작 화면과 앱들은 어떠한 사용자 경험의 향상도 없고, 데스크탑과 메트로 바탕화면을 왔다 갔다 하는 것이 오히려 불편하다.
물론, 데스크탑 응용 프로그램을 데스크탑 바탕화면에 바로가기 아이콘을 생성하거나 테스크바(Task Bar)의 핀(Pin)으로 고정할 수 있는 편리한 방법도 제공해 준다. 하지만 이것은 필자가 언급하는 근본적인 해결책이 아니므로 논외로 하겠다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 아크몬드 2012.08.10 09:07 Address Modify/Delete Reply

    우와.. 재밌는데요..ㅋㅋ

    저도 그동안 생각하고 있었던 점을 정리해서 올려보렵니다.
    간만에 열혈 윈도우 포스팅 본 것 같아 아련하네요. 이런 글 본지가 언젠지...

    잘 보고 갑니다.

  2. TY LEE 2012.09.08 03:45 Address Modify/Delete Reply

    필자는 개발자 출신인가.. 엠에스가 전략을 바꾼건 시대의 트랜드를 읽어냈다는 것이고 그건 잘한것이라 본다. 트랜드란게 곧 대중의 요구다. 몇몇 엔지니어 비유맞추기보다는 대중을 선택한것이지. 전문지식이 없어 메트로니 콘솔이니.. 정확한 의미는 모르겠다만 필자의 글의 문맥상 대략은 그 뜻이 그려지는데, MS가 이런 인터페이스를 시도한건 논리적인 UI에서 직관적인 UI로 넘어가려는것이다. 미래에 모든 디바이스들의 유저인터페이스는 이런 환경으로 바뀔것이다. 스마트폰을 사용하는데 사용설명서를 읽고 쓰는 사람이 있던가 (어르신들은 좀 논외로하자-필자식 꼬리자르기) 그 스마트폰에 시작버튼이 있던가. 직관적으로 찾아가는 것이다. 그것이 훨씬 재미와 감동을 준다. 오히려 그런 손동작과 눈동자의 움직임으로 좌뇌보다 우뇌를 사용하게 된다. 폴더타령하고 체계적인 분류를 원하는 분들은 좀 이해가 안갈수도 있다. 우리의 직관을 믿으시라. 아직 더 많이 바뀌어야하지만, 시작버튼이 없어진것은 기계가 좀더 인간과 가까워지고 생명력을 얻었다는 신호탄이다. 이방법으로 해당 앱이나 기타목표물을 찾아가는 그 과정에서 불편함을 느낀다면 그것은 디자인이 잘못된것이지, 근본적인 이 접근방법이 잘못된것이 아니다. 그런부분은 애플이 한수위인듯하다.

  3. 현천이 2012.10.05 23:02 Address Modify/Delete Reply

    와 진짜 잘 짚었음. 설치한지 5분만에 시작을 대체할 방법을 찾기 시작하고, 10분만에 바탕화면에 가는 방법을 찾아야 함. 정말 망작 필이 솔솔 남.

    윈도우 7의 성공요소와 비스타의 실패 요인도 정확하게 짚었음.
    개인적으로, 이번 8과 비스타의 최대 망작요소는 항상 마소의 고질적인 문제 - 개발한 프로그램을 사용하도록 강요된 환경 - 에서 출발함. 메트로 기능은 잘 쓰면 매우 좋지만, 사용하라고 강요하는 환경에서는 너무나 부담스러움.

  4. 하두호 2012.11.07 15:07 Address Modify/Delete Reply

    와 진짜 제가 하고 싶은 말들만 쏙쏙 적어 두셨네요 윈8 나쁘진 않은데 본문같은 단점들은 정말 이해하기 힘든 부분입니다

아마 IT 트랜드에 관심이 많거나 이 분야에서 일하시는 분이라면 관심 있게 볼 수 있는 TV 프로그램이 있다. LIVE SMART SHOW의 "직설 IT 수다" 프로그램이다. 이 프로그램은 IT 트랜드에 대한 주제를 놓고 4명의 고정 게스트가 여러 가지 의견을 나누고 여러 각도로 주제를 재조명하는 재미있는 프로그램 중 하나라고 할 수 있다.











이번 MS OFFICE 2013에 대해 뜨거운 감자로 '과연 MS OFFICE가 시장을 지속적으로 영위할 수 있을 것인가' 에 대한 것이다. Microsoft의 킬러 앱이라고 하면 단연 "Microsoft Office(MS OFFICE)"라고 할 수 있는데, 이 자리를 노리는 많은 웹 서비스가 있고 그것이 대안이 될 수 있다는 것에 잠시 초점이 맞추어졌다.

 

구글 Docs, 에버노트의 웹 서비스가 MS OFFICE 시장을 빼앗을 수 있을까?

필자는 답부터 말하면 "No" 라고 말하고 싶다.

대표적으로 구글 Docs와 MS OFFICE의 가장 큰 차이점이라고 하면, 구글 Docs는 웹 서비스이고, MS OFFICE는 데스크탑 응용 프로그램이다. 그리고 최근 MS OFFICE는 SaaS(Software As a Service) 형태를 띄며 '공유, 모바일' 그리고 클라우드까지 서비스 영역을 확장하는 시도를 하고 있다. (이미 클라우드와 제한적인 연동을 지원한다.)

여기에서 뜨거운 감자로 떠오르는 것이 굳이 MS OFFICE를 대체할 수 있다는 것이다. 구글 Docs를 써보면 충분히 웹 브라우저를 이용하여 웹에서 문서를 편집하고 공유할 수 있다. 웹이라고 하는 용이한 접근성으로 PC에 설치를 해야 하는 MS OFFICE를 구매할 필요성이 점차 낮아지고 있다는 점을 지적하고 있다.

필자는 이 점을 공감하고 있다. MS OFFICE는 라이선스를 구매해야 하며, PC에 설치해야 하며, 로컬 컴퓨터를 주요 스토리지로 사용한다는 점에서 구글 Docs에 비해 단점이라고 할 수 있다. 그리고 간단한 문서를 작성하거나 편집하기 위해서는 구글 Docs의 웹 서비스를 사용하는 것이 훨씬 이득이다. 그리고 온라인상에서 여러 사람과 동시에 문서를 작성/편집하는 등 책이나 출판을 목적으로 구글 Docs를 사용하는 경우도 있다.

MS OFFICE는 이름에서도 알 수 있듯이 사무자동화(OA) 업무에 사용하기 편리하다. OUTLOOK, EXCEL, WORD, POWERPOINT, SHAREPOINT WORKSPACE, ONENOTE 등의 소프트웨어들이 MS OFFICE 제품으로 엮인다. 그리고 SKYDRIVE의 클라우드 저장소와 연동이 되며, SKYDRIVE에서 문서를 열거나 만드는 경우 웹에서 직접 문서를 작성/편집이 가능하다. 웹에서 MS OFFICE 기능을 제공하는 것을 "Web App" 이라고 하는데, SHAREPOINT를 사용하는 경우 인트라넷에서 웹에서 OFFICE의 대부분의 기능을 제공한다. 데스크탑 오피스를 웹으로 고스란히 옮겨놓은 것이라고 보아도 무방할 정도의 퀄리티이다.

아래와 같이 필자는 크롬 브라우저를 이용하여 SKYDRIVE에 저장해 놓은 POWERPOINT 문서를 열어보았다. 완벽하게 애니메이션까지 재생이 된다. WORD, EXCEL 등의 문서 포멧을 지원한다.

 













하지만, 사람들마다 성향이 다르듯이 필자는 구글 Docs를 쓰려고 노력해봐도, 에버노트를 쓰려고 노력해봐도 불편함부터 느껴진다. 단지 언제든지 불의의 사고로 복원이 필요한 경우를 대비하여 아이폰, 아이패드 동기화 용도로만 쓸 뿐이다.

 

"구글은 당신이 지난 여름에 한 일을 알고 있다"

구글은 정말 많은 무료 서비스를 제공한다. 그 중에서 메일 서비스(GMAIL) 또한 구글의 강력한 킬러 서비스 중 하나인데, 예전에 구글 메일과 관련된 일화가 있다. 친구와의 하와이 여행을 위해 구글 메일로 하와이에 대한 이야기를 주고 받았는데, 어느 날 구글 메일 페이지 내의 광고에서 "하와이…" 에 대한 맞춤 광고가 떴다는 것이 주요 골자이다.

그 밖에 일화도 있다. "[영상]"구글 메일이 당신의 사생활을 훔쳐본다"

구글이 내놓은 모든 무료 서비스는 구글에게 가장 가치 있는 "키워드"라는 정보를 수집할 필요가 있다. 이 키워드는 트랜드를 반영하기도 하며, 이슈 또는 비전을 제시할 수 있다. 또 한가지는 구글 메일은 강력한 스팸 차단 기술을 보유하고 있다. 필자가 써본 메일 중에 스팸 차단이 가장 잘 된다고 느낀다. 스팸 차단 기술은 기본적으로 차단된 제목 또는 일부 내용이 차단된 키워드를 포함하고 있는 경우 스팸으로 분류하기도 하고, 특히 구글 메일은 이보다 더 효과적이고 강력한 알고리즘을 사용한다. 그럼에도 불구하고 많은 벤처 기업과 중소 기업은 구글 메일을 기업 메일로 도메인을 연결하여 사용하기도 한다.

구글은 당신의 이메일이나 구글Docs 의 정보를 스캔한다고 보면 된다. 극단적으로 구글이 당신의 정보를 스캔하지 않는다고 해도, 이미 당신의 정보는 더 이상 당신의 정보가 아니다. 왜냐하면 당신이 원하는 만큼 제어할 수 없는 곳인 구글 서버에 당신의 정보가 저장이 되어 있기 때문이다.

이제는 굳이 구글을 해킹을 하지 않더라도 개인정보를 훔치는 것은 생각보다 쉬워졌다. 국내에서는 이미 옥션, 넥슨, 네이트온, KT 에서 우리나라 전체 인구인 약 5천만보다 수 백배가 많은 개인 정보가 노출이 되었고, 이 정보로 타인의 개인정보에 접근이 쉬워졌다. 쉽게 말하면, 만약 우리나라 대통령 "이명박" 각하가 옥션, 네이트온, KT에 가입되었다면 해킹된 정보만으로도 "이명박" 각하의 보안 정보에 접근할 수 있는 정보가 충분히 제공된다.

 

다시 원점으로 돌아가보자. 최신 운영체제는 파일에 강력한 보안을 적용할 수 있는 기능을 제공한다. 무료/유료로 제공되는 인트라넷의 자원을 통합하여 관리할 수 있는 소프트웨어도 있다. (유료 소프트웨어 중 SHAREPOINT가 대표적). 그리고 전사적인 자원을 통합 관리, 보안, 제어할 수 있는 Active Directory와 같은 기술도 있다.

물론 처음부터 모든 구색을 갖추고 시작하는 벤처나 기업이 없는 경우가 더 많다. 하지만, 무료로 제공되는 여러 가지 클라우드 서비스는 서비스 제공자에게 있어 "무료가 아닐 수 있다". 왜냐하면 많은 클라우드 서비스는 "당신이 지난 여름에 한 일을 알고 있기 때문이다." 우리가 무료 웹 서비스를 즐길 수 있는 댓가를 무료 웹 서비스에게 지불한다는 점을 항상 잊어서는 안된다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 아크몬드 2012.08.03 09:50 Address Modify/Delete Reply

    재밌게 읽고 갑니다.

본 아티클은 MSDN 에 eBook으로 공개된 문서를 블로그 아티클로 편집하였습니다. VSTS 팀블로그에 의해 작성된 문서의 원문 및 여러 가지 기술 문서는 아래의 링크에서 PDF로 다운로드 받을 수 있습니다. 그리고 본문의 특정 버전을 지칭하는 개발툴 버전 번호는 모두 Visual Studio로 변경되었음을 참고하십시오. (예- Visual Studio 20xx는 Visual Studio로 표기함 )

VSTS 팀블로그 MSDN 기술 문서 : http://msdn.microsoft.com/ko-kr/gg620748 

필자 소개

Microsoft Visual Studio ALM MVP 엄준일
http://blog.powerumc.kr

 

Visual Studio Korea Team Blog
http://vsts2010.net

감수 : 강성재 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

   

도움주신 분 : 김남영 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

 

[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 1/7 - 들어가기에 앞서...
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 2/7 - 왜 모델링인가?
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 3/7 - 모델링의 표기
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 4/7 - 모델링 다이어그램
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 5/7 - Visualization & Features Pack
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 6/7 - 모델링 확장 (SDK)
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 7/7 - 결론 및 저자 소개

 

8. 결론

백서에서 지금까지 Visual Studio을 활용하여 어플리케이션을 모델링하고 그리고 모델링을 확장하여 잘 이용할 수 있는 여러 가지 기능과 방법을 설명하였습니다. 혹여 이 백서를 읽는 독자가 회사에서 UML 또는 모델링을 하는 업무나 직책을 갖지 않더라도 분명히 모델링은 개발자 사이에도 어느 정도 필요로 합니다.

소위 개발자들은 "코드로 말한다" 라고 강조하기도 합니다. 하지만 코드로 말하기 전에 자신의 의도와 노력을 시각적으로 표현하기 위해 노력하는 방법도 매우 중요합니다. 그것은 코드가 완성이 되기 전에 서로 간의 커뮤니케이션을 할 수 있으므로 이해 관계가 복잡해 질 때 먼저 자신의 의도와 노력을 상대에게 이해시킬 수 있는 좋은 방법이 바로 모델링이기 때문입니다.

이러한 모델링 습관은 매우 좋은 현상입니다. 예전에 값 비싼 도구로 모델링을 할 수 있었지만 이제는 Visual Studio으로 시스템의 설계나 코드의 설계, 그리고 기존 코드를 시각화 함으로써 서로 간에 시스템이나 어플리케이션의 설계 또는 코드를 쉽게 이해하고 접근하는 좋은 방법이기도 합니다.

더불어 Visual Studio의 모델링은 지속적으로 발전하고 있고 다양한 모델링 확장 기능을 Visual Studio Gallery 사이트에서 제공하고 있습니다. 모델링은 통합 개발 도구와 통합하여 보다 기존보다 좀더 생산성 있고 가치 있는 활동을 하나의 도구에서 모두 할 수 있으며, 이러한 여러분의 노력이 한 걸음 더 뻗어 나갈 수 있는 좋은 스킬이 되리라 필자는 확신을 합니다.

 

  • 저자 소개
    현재 필자는 NCSOFT에 재직하지 않음을 참고하기 바랍니다.


  • 오픈 소스 개발

1) MEFGeneric (2010년) - http://mefgeneric.codeplex.com/
.NET Framework 4.0에 포함된 MEF 라이브러리가 제공하지 않는 제네릭(Generic) 타입을 지원하도록 개선한 프로젝트

2) VSGesture for Visual Studio (2010년~) - http://vsgesture.codeplex.com/
Visual Studio에서 마우스 제스처를 통해 빌드, 디버깅, 화면 제어를 하는 확장 도구 프로젝트

3) Umc.Core Enterprise Framework(2012년~) - http://umccore.codeplex.com/
IoC, AOP, Build, Mapping 등의 오픈 소스를 직접 구현하여, 하나의 엔터프라이즈 프레임워크로 제공하는 프로젝트

4) vutpp for Visual Studio (2011년~) - http://vutpp.codeplex.com/
Visual C++ 에서 단위 테스트를 지원하는 확장 도구 프로젝트

5) jQuery DateTimePicker Plugin (2012년) - http://umcdatetimepicker.codeplex.com/
jQuery Plugin 중 DatePicker에 시간 선택 기능을 추가한 jQuery 플러그인 프로젝트

6) 설치형 블로그 (2007년) – http://blog.powerumc.kr/30
ASP.NET 국내 최초로 오픈 소스로 공개된 설치형 블로그 프로젝트

 

  • MSDN (개발자 네트워크) 기술 자료 제공 (PDF)

1) MSDN 게시: Visual Studio 응용 프로그램 모델링 완전 정복 백서
2) MSDN 게시 및 출판 : Visual Studio 2010 을 활용한 ALM(Application Lifecycle Management)
3) MSDN 게시: Team Foundation Server 2010 설치 가이드 (단일 서버)
4) MSDN 게시: Team Foundation Server 2010 설치 가이드 (다중 서버)
5) MSDN 게시: Team Foundation Server 2010 설치 가이드 (Lab 구성)
6) MSDN 게시: Team Foundation Server 2010 활용 가이드 (FQDN 설정)
7) 7) MSDN 게시: VSS 사용자를 위한 Team Foundation Server 2010 시리즈 (WORKGROUP 설치가이드)
8) MSDN 게시: VSS 사용자를 위한 Team Foundation Server 2010 시리즈 (활용가이드)
9) MSDN 게시: VSS 사용자를 위한 Team Foundation Server 2010 시리즈 (마이그레이션가이드)

 

  • 월간 마이크로소프트 비정기 기술 자료 기고

1) 2008년 10월호 : Visual Studio 2008 Service Pack 1 with .NET Framework 3.5 SP1
2) 2009년 08월호 : Visual Studio 2010
3) 2010년 03월호 : 닷넷 길라잡이 | ALM의 정의와 세 가지 요소
4) 2010년 04월호 : 닷넷 길라잡이 | Visual Studio 2010을 활용한 ALM
5) 2010년 05월호 : 닷넷 길라잡이 | 명확한 작업의 관리와 지속적인 통합 - 추적성
6) 2010년 06월호 : 닷넷 길라잡이 | 과거와 현재를 알면 미래가 보인다 - 가시성
7) 2010년 07월호 : 닷넷 길라잡이 | 테스트와 가상화의 만남
8) 2012년 05월호 : 비주얼 스튜디오 11, 윈도우8 시대를 대비하자, C++/CX 이해하기

 

  • ZDNET Korea 비정기 기술 자료 기고

1) 2010년 04월 28일 : 지속적인 통합을 넘어선 ALM의 미래-1
2) 2010년 05월 01일 : 지속적인 통합을 넘어선 ALM의 미래-2

 

  • 세미나

1) Visual Studio Camp #1 : (2010/08/28) 소프트웨어 품질 향상을 위한 다양한 테스트 기법
2) REMIX10 : (2010/06/01) : 혁신적인 프로그램을 만드는 .NET 4 와 비주얼 스튜디오 2010
3) TECHDAYS 2010 : NET Framework 4.0, MEF(Managed Extensibility Framework)
4) TECHDAYS 2009 : Visual Studio Team System 2010 With Agile
5) DEVDAYS 2008 : 개발자가 꼭 알아야 할 .NET 프레임워크 하이라이트 – 2.0에서 3.5 SP1 까지
6) Microsoft MVP 대상 기술 세미나 : (2009/01/14) Visual Studio Team System 2010
7) Visual Studio 팀 세미나 : MEF(Managed Extensibility Framework) within .NET Framework 4.0
8) 첨단 기업 연구소를 위한 무결점 소프트웨어 세미나 : (2012/04/24)

Posted by 땡초 POWERUMC

댓글을 달아 주세요

  1. 1 2013.03.27 20:20 Address Modify/Delete Reply

    프로그래머와 작업의뢰인의 거래사이트 "오투잡"

    오투잡은 현재 하루 접속자 3000명이 접속하는 재능거래 사이트 입니다.
    오픈한지 얼마되지 않았지만 부업분야 전체 점유율 2위, 국가지원을 받고있습니다.

    오투잡에서 판매자 대모집 중입니다.
    카테고리 활성화가 시작 되니, 많은 판매 등록 바랍니다.
    오투잡은 네이버에서 "오투잡" 으로 검색 하세요.

본 아티클은 MSDN 에 eBook으로 공개된 문서를 블로그 아티클로 편집하였습니다. VSTS 팀블로그에 의해 작성된 문서의 원문 및 여러 가지 기술 문서는 아래의 링크에서 PDF로 다운로드 받을 수 있습니다. 그리고 본문의 특정 버전을 지칭하는 개발툴 버전 번호는 모두 Visual Studio로 변경되었음을 참고하십시오. (예- Visual Studio 20xx는 Visual Studio로 표기함 )

VSTS 팀블로그 MSDN 기술 문서 : http://msdn.microsoft.com/ko-kr/gg620748 

필자 소개

Microsoft Visual Studio ALM MVP 엄준일
http://blog.powerumc.kr

 

Visual Studio Korea Team Blog
http://vsts2010.net

감수 : 강성재 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

   

도움주신 분 : 김남영 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

 

[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 1/7 - 들어가기에 앞서...
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 2/7 - 왜 모델링인가?
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 3/7 - 모델링의 표기
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 4/7 - 모델링 다이어그램
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 5/7 - Visualization & Features Pack
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 6/7 - 모델링 확장 (SDK)
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 7/7 - 결론 및 저자 소개

 

7. Visual Studio Modeling SDK

Vual Studio 2010 SDK(Software Development Kit)은 기존의 Visual Studio의 기능을 확장할 수 있는 도구를 지원해 주고 있습니다. 이 내용에 대해 자세한 내용은 필자의 블로그의 다음의 글을 참고 하십시오.

참고

[VSX] 1. Visual Studio Extensibility,, 그 시작

http://blog.powerumc.kr/232

 

7.1. 개발 환경 및 설치 요구 사항

Visual Studio 모델링 프로젝트를 확장하기 위해 먼저 Visual Studio SDK를 설치해야 합니다. Visual Studio SDK 는 아래의 다운로드 주소를 통해 다운로드 받으실 수 있습니다.

Visual Studio SDK 다운로드

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=47305cf4-2bea-43c0-91cd-1b853602dcc5&displaylang=en

 

시스템 요구 사항

  • Supported Operating Systems: Windows 7;Windows Server 2003 R2 (32-Bit x86);Windows Server 2003 R2 x64 editions;Windows Server 2003 Service Pack 2;Windows Server 2008 R2;Windows Server 2008 Service Pack 2;Windows Vista Service Pack 2;Windows XP Service Pack 3
    • Windows XP (x86) with Service Pack 3 - all editions except Starter Edition
    • Windows Vista (x86 & x64) with Service Pack 2 - all editions except Starter Edition
    • Windows 7 (x86 and x64)
    • Windows Server 2003 (x86 & x64) with Service Pack 2 - all editions
    • Users will need to install MSXML6 if not already present
    • Windows Server 2003 R2 (x86 and x64) - all editions
    • Windows Server 2008 (x86 and x64) with Service Pack 2 - all editions
    • Windows Server 2008 R2 (x64) - all editions

 

Visual Studio 2010 요구 사항

  • Visual Studio 2010 Professional or better

 

7.2. Layer Diagrams 확장하기

Visual Studio  SDK와 Visual Studio 2010 Visualization & Modeling Features Pack을 설치하면 Layer Diagrams을 확장할 수 있는 프로젝트 템플릿이 설치가 됩니다.

새 프로젝트 만들기에서 모델링 프로젝트->Extensibility 를 선택하면 세 가지의 새로운 템플릿이 생성이 된 것을 확인할 수 있습니다.

각 템플릿은 Layer Diagrams을 확장하기 위해 아래와 같은 기능을 수행하는 템플릿입니다.

  • Command Extension
    Layer Diagrams에 특정 컨텍스트 메뉴를 통해 명령을 수행할 수 있는 확장 기능을 만들 수 있습니다.

  • Gesture Extension
    Layer Diagrams으로 끌어오기 동작 등의 확장 기능을 만들 수 있습니다.

  • Validation Extension
    Layer Diagrams과 코드의 구조가 유효한지 검사하는 확장 기능을 만들 수 있습니다.

 

7.2.1. 레이어 개수를 세는 Command Extension 만들기

 

7.2.1.1. Layer Diagrams Command Extension 프로젝트 생성

우선 간단한 Command Extension을 만들기 위해 Command Extension 템플릿으로 프로젝트를 생성합니다. 프로젝트의 이름을 CustomLayerCommand (또는 희망하는 이름으로) 프로젝트를 생성합니다.

 

간단히 생성된 프로젝트를 실행 또는 디버깅 하기 위해서 생성된 Command Extension 프로젝트를 선택하여 마우스 오른쪽 버튼을 클릭하여 시작 프로젝트로 설정합니다.

 

그런 다음 F5 키를 눌러 디버깅을 시작합니다. F5키를 눌러 디버깅을 시작하면 Visual Studio 2010은 별도의 레지스트리를 사용하는 Experimental 모드로 실행을 하게 되어 기존의 Visual Studio 2010에 영향이 없도록 동작하게 됩니다.

 

7.2.1.2. Layer Diagrams에 명령 코드 만들기

Visual Studio 의 새로운 확장 기능은 .NET Framework 4.0에 포함되는 MEF(Managed Extensibility Framework)를 사용하여 확장 기능을 만들 수 있습니다. 모델링 확장 기능 또한 MEF를 사용하여 확장할 수 있으며 MEF에 대한 자세한 내용은 필자의 블로그를 참고 하시기 바랍니다.

참고

MEF(Managed Framework Extensibility) 연제
http://blog.powerumc.kr/189

 

우선 클래스의 선언은 다음과 같이 되어 있습니다 아래와 같이 ExportAttribute을 사용하여 ICommandExtension 형식을 Visual Studio 모델링에서 인식할 수 있도록 컴포넌트 계약을 합니다. 그리고 LayerDesignerExtensionAttriburte을 추가하면 Layer Diagrams에서 ICommandExtension 확장 기능을 사용할 수 있도록 합니다.

[Export(typeof(ICommandExtension))]
[LayerDesignerExtension]
public partial class CustomLayerCommandExtension : ICommandExtension 


클래스 내부에 Import된 IDiagramContext는 현재 다이어그램의 컨텍스트 개체로 이 개체를 이용하여 특정 명령을 내릴 때 다양한 작업을 수행할 수 있습니다.

[Export(typeof(ICommandExtension))]
[LayerDesignerExtension]
public partial class CustomLayerCommandExtension : ICommandExtension
{
    [Import(typeof(IDiagramContext))]
    public IDiagramContext DiagramContext { getset; } 


ICommandExtension의 인터페이스는 Text 속성을 구현해야 하는데 이 속성은 다이어그램 컨텍스트 메뉴에서 표시되는 메뉴 이름입니다.

public string Text
{
    get	
    {
        return "레이어 개수";
    } 
} 


ICommandExtension의 인터페이스는 QueryStatus를 구현해야 하는데, 현재 상태에서 컨텍스트에 표시될 수 있는지 여부를 나타내게 됩니다. 조건에 따라 다른 표시/보이기 등의 동작이 필요하다면 아래의 코드를 수정하시면 됩니다.

public void QueryStatus(IMenuCommand command)
{
            command.Visible = true;
            command.Enabled = true} 


마지막으로 ICommandExtension의 Execute 메서드를 구현합니다. 이 메서드는 Layer Diagrams의 레이어 개수를 계산하기 위해 재귀 호출을 통해서 레이어 요소의 개수를 카운트합니다.

public void Execute(IMenuCommand command)
{
    int layerCount = 0;
    this.VisitDiagramElement(this.DiagramContext.CurrentDiagram.Diagram.ChildShapes, ref layerCount);

 

    MessageBox.Show(String.Format("레이어의 개수는 모두 {0}  입니다.", layerCount));            
}

 

private void VisitDiagramElement(IEnumerable<IShape> shapes, ref int layerCount)
{
    foreach (var shape in shapes)
    {
        if (shape != null && shape.GetLayerElement() is ILayer)
        {
            layerCount++;

 

            if( shape.ChildShapes.Count() > 1) 
                this.VisitDiagramElement(shape.ChildShapes.Skip(1), ref layerCount);
        }
    } 
} 


7.2.1.3. Layer Diagrams 코드 실행 결과

먼저 작성된 코드를 실행하기 위해 Visual Studio 에서 Command Extension을 시작 프로젝트로 설정한 후에 F5 키를 눌러 Visual Studio Experimental 모드로 실행을 할 수 있습니다. 만약 디버깅이 필요하지 않다면 Ctrl+F5 키를 눌러 디버깅 없이 실행하여 실행 속도를 높일 수 있습니다.

위의 코드는 다음과 같이 Layer Diagrams에서 마우스 오른쪽 버튼을 눌러서 활성화할 수 있습니다. 다음과 같이 Text 속성의 반환 값이 메뉴의 이름이 되는 것을 확인할 수 있습니다.

 

해당 메뉴를 클릭하면 Execute 메서드가 실행이 되고 메시지 상자에 Layer Diagrams에 포함된 모든 레이어의 개수를 표시해 줍니다.

 


7.2.2. 폴더 구조를 DRAG&DROP 하는 Gestures Extension 만들기

7.2.2.1. Geatures Extension 프로젝트 만들기

새로운 프로젝트를 생성하는 메뉴에서 모델링 프로젝트->Extensibility 항목에서 Layer Designer Gesture Extension 을 선택하고 확인을 클릭합니다.

 

이 후 설정은 Layer Diagrams Command Extension 프로젝트 생성 항목을 참고하십시오.

 

7.2.2.2. 폴더를 Drag&Drop 하는 코드 만들기

Gesture Extension 은 IGestureExtension 인터페이스를 구현합니다. 이 인터페이스를 상속하는 클래스를 만든 후에 ExportAttribute을 통해 Visual Studio 2010의 모델링 Geature Extension과 계약 관계를 형성합니다.

[Export(typeof(IGestureExtension)), LayerDesignerExtensionpublic partial class CustomLayerGestureExtension : IGestureExtension 


폴더를 Drag&Drop 하는 코드 전체는 다음과 같습니다.


[Export(typeof(IGestureExtension)), LayerDesignerExtension]
partial class CustomLayerGestureExtension : IGestureExtension
{

        [Import(typeof(IDiagramContext))]
        public IDiagramContext DiagramContext { getset; }

 

        public void OnDoubleClick(IShape target) { }

 

        public bool CanDragDrop(IShape target, IDataObject data)
        {
            var folders = data.GetData(DataFormats.FileDrop) as String[];
            if (folders == null)
            {
                MessageBox.Show("가져올 데이터가 없습니다.");
            }

 

            var isValidate = true;
            foreach(var folder in folders)
            {
                if( System.IO.Directory.Exists(folder) == false )
                {
                    isValidate = false;
                    break;
                }
            }

 

            return true;
        }

 

        public void OnDragDrop(IShape target, IDataObject data)
        {
            var folders = data.GetData(DataFormats.FileDrop) as String[];

 

            foreach (var folder in folders)

            {                 var dirInfo = new System.IO.DirectoryInfo(folder);                 target.Diagram.GetLayerModel().CreateLayer(dirInfo.Name);             }         } }

 


7.2.2.3. 폴더를 Drag&Drop 하는 Gesture Extension 코드 실행 결과

먼저 테스트로 진행할 모델링 프로젝트를 생성한 후에 Layer Diagrams 항목을 추가 합니다.

그리고 윈도우 탐색기를 열어 드래그할 폴더를 다음과 같이 선택합니다.

 

선택할 폴더 항목을 Visual Studio 2010의 다이어그램 디자이너에 Drag하여 Drop합니다.

 

Drop 결과 해당하는 폴더의 이름대로 Layer Diagrams의 레이어 요소가 생성이 되는 결과를 확인할 수 있습니다.

Posted by 땡초 POWERUMC

댓글을 달아 주세요

본 아티클은 MSDN 에 eBook으로 공개된 문서를 블로그 아티클로 편집하였습니다. VSTS 팀블로그에 의해 작성된 문서의 원문 및 여러 가지 기술 문서는 아래의 링크에서 PDF로 다운로드 받을 수 있습니다. 그리고 본문의 특정 버전을 지칭하는 개발툴 버전 번호는 모두 Visual Studio로 변경되었음을 참고하십시오. (예- Visual Studio 20xx는 Visual Studio로 표기함 )

VSTS 팀블로그 MSDN 기술 문서 : http://msdn.microsoft.com/ko-kr/gg620748 

필자 소개

Microsoft Visual Studio ALM MVP 엄준일
http://blog.powerumc.kr

 

Visual Studio Korea Team Blog
http://vsts2010.net

감수 : 강성재 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

   

도움주신 분 : 김남영 부장
한국마이크로소프트 개발자 및 플랫폼 사업 총괄

 

[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 1/7 - 들어가기에 앞서...
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 2/7 - 왜 모델링인가?
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 3/7 - 모델링의 표기
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 4/7 - 모델링 다이어그램
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 5/7 - Visualization & Features Pack
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 6/7 - 모델링 확장 (SDK)
[Enterprise Architecture/Architecture] - 개발자도 알아야 할 응용 프로그램 모델링 7/7 - 결론 및 저자 소개

 

6. Visual Studio Visualization & Modeling Features pack

Visual Studio Visualization & Modeling Features Pack(이하 Modeling Features Pack)은 2010년 12월 4일 MSDN 구독자에게 공개가 되었습니다. 이 Modeling Features Pack은 기존의 모델링 프로젝트에서 지원하지 않았던 몇 가지 기능을 보강하는 도구로써 Modeling Features Pack과 Modeling Features Pack Runtime을 제공해 줍니다.

 

6.1. Modeling Features Pack 개요

Visual Studio의 Modeling Features Pack은 다음과 같은 기능을 제공해 줍니다.

  • C++ 및 ASP.NET 프로젝트의 종속성 그래프 지원
  • C++ 코드에서 Layer Diagrams의 아키텍처 유효성 지원
  • UML Class Diagrams을 코드로 변환하거나 코드를 UML 다이어그램으로 변환
  • XMI 2.1 파일로 내보내기 기능
  • 다이어그램의 요소와 Team Foundation Server의 작업 항목 연동 강화
  • Layer Diagrams 확장

 

6.2. ASP.NET 웹 프로젝트의 종속성 그래프 분석

기존에 종속성 그래프 분석은 닷넷의 어셈블리나 클래스를 기준으로 분석이 되어 웹 프로젝트의 경우 ASPX 파일이나 그에 해당하는 종속성을 분석하기란 사실상 불가능 하였습니다. 다만 웹 프로젝트를 클래스나 어셈블리 수준에서 분석이 가능하였으나 웹 프로젝트 특성을 잘 반영한 종속성을 분석하기는 어려움이 많았습니다.

이번 ASP.NET 종속성 그래프는 웹 프로젝트라는 특성을 잘 반영하여 페이지 파일이나 공통되는 마스터 페이지 등 종속성 분석이 한결 자연스러워졌습니다.

ASP.NET 종속성 그래프 생성은 다음과 같은 웹 프로젝트 형식을 지원합니다.

  • ASP.NET 웹 사이트
  • ASP.NET 웹 프로젝트
  • ASP.NET MVC 웹 프로젝트

 

6.2.1. 웹 프로젝트 종속성 그래프를 만들려면?

  1. 종속성 그래프를 분석할 웹 프로젝트를 로드 합니다.
  2. 아키텍처->종속성 그래프 생성에 By Web Site 외 모두 두 가지 항목이 새로 생겼습니다. 코드 종속성과 함께 ASP.NET 웹 프로젝트를 분석하려면 By Web Site with Code Dependencies 를 선택합니다.


  3. 솔루션에서 웹 프로젝트의 종속성을 분석합니다.

     

  4. 다음은 웹 프로젝트의 전체를 코드 종속성 분석과 함께 분석된 결과 입니다.

     

 

6.2.2. 종속성 그래프를 분석하려면?

다음과 같이 종속성 그래프를 확대하면 각 페이지 간의 종속성을 보여줍니다.

이 종속성 그래프는 DGML(Directed Graph Markup Language)로써 웹 프로젝트 뿐만 아니라 Visual Studio의 전반적인 분석에 사용되는 전용 마크업 언어이기도 합니다.

만약 특정 페이지가 어떤 모듈이나 페이지간에 종속성을 미치는지 확인하기 위해서 해당 노드를 선택하면 됩니다. 예를 들어 아래의 AccountController 클래스가 가지는 종속적인 관계는 ChangePassword.aspx, ChangePasswordSuccess.aspx 등의 각 페이지들과 인증과 관련된 FormAuthenticationService, ChangePasswordModel 클래스 등에 종속적인 관계를 갖는 것을 확인할 수 있습니다.

 

이 AccountController 클래스의 내부를 좀더 자세히 보기 위해서는 AccountController 노드의 오른쪽 상단의 화면표 아이콘을 선택합니다.

 

그럼 AccountController가 구현하는 메서드나 프로퍼티 정보를 표시합니다.

 

만약 이 메서드들이 어떤 종속성을 갖는지 알기 위해서 메서드의 하나의 노드를 선택하면 됩니다. 예를 들어 아래의 get_MembershipService (원래는 속성(Property)임)은 다양한 메서드에서 호출되는 속성인 것을 확인할 수 있습니다.

 

이러한 종속성 정보는 얼마나 복잡하게 서로간에 영향력을 미치는지 알 수 있습니다. 예를 들어, 화살표를 많이 받으면 받을수록 그 코드의 변경이 주는 전파력은 상당히 높아지며, 코드에 버그가 있다면 그 버그의 전파력은 종속성이 갖는 크기만큼인 것이 될 것이라 예상할 수 있습니다.

 

종속성 그래프에서 화살표를 더블 클릭하여 분석할 종속성의 레벨을 지정할 수 있습니다.

 

만약 웹 프로젝트를 코드 레벨에서 분석을 하길 원한다면 종속성 그래프의 컨텍스트에서 마우스 오른쪽 버튼을 클릭하여 Get Code Dependencies 를 선택합니다.

 

그럼 웹 프로젝트의 노드를 확장하면 웹 프로젝트의 페이지 등의 종속성의 분석이 아닌 코드 레벨에서 종속성을 분석해 줍니다.

 

코드 레벨의 종속성을 분석하면 다음 그림과 같이 해당 노드와 종속되는 페이지를 확인할 수 있습니다.

 

 

6.3. UML 다이어그램과 코드 간의 상호 변환

 

6.3.1. Class Diagrams을 코드로 변환하기

Class Diagrams을 코드로 변환하기 위해서 모델링 프로젝트에서 UML Class Diagrams을 새로 추가 합니다.

 

  1. 간단하게 다음과 같이 클래스 모델링을 해 봅시다. 각각 Member, Phone, Address 클래스 요소를 추가 합니다.


  2. Member 클래스 요소를 Phone, Address 클래스 요소와 연결(Association) 관계로 만듭니다. 연결 관계로 만들기 위해서 Member 클래스 요소를 마우스 오른쪽 버튼으로 클릭한 후 추가->연결(Association) 항목을 클릭하여 각각 Phone, Address 클래스 요소와 연결합니다.


  3. 다음의 그림은 연결(Association) 을 Phone, Address 클래스 요소와 연결한 그림입니다.


  4. 모든 작업이 완료 되었으면 Class Diagrams의 컨텍스트 메뉴에서 Generate Code 를 클릭합니다.


  5. 다음과 같이 새로운 프로젝트가 생성이 되고, GenerateCode 폴더에 Class Diagrams의 클래스 요소들이 코드로 변환이 됩니다.


  6. Member.cs 클래스 파일은 다음과 같이 Phone, Address 클래스와 연결 관계가 속성으로 변환이 된 것을 확인할 수 있습니다.

 

 

6.3.2. 코드를 Class Diagrams으로 변환하기

마찬가지로 Visual Studio Modeling Features Pack은 기존에 존재하는 코드를 UML Class Diagrams으로 변환할 수 있습니다.

 

  1. 아래와 같이 간단하게 코드를 작성합니다. 기존 코드가 있으시면 기존 코드를 사용하셔도 무방합니다.

     

  2. 만약 모델링 프로젝트가 현재 솔루션에 없다면 모델링 프로젝트를 생성합니다. 아키텍처->새 다이어그램을 선택하여 UML Class Diagrams을 생성합니다.

  3. 아키텍처->창->아키텍처 탐색기를 선택합니다.



  4. 아키텍처 탐색기에서 UML Class Diagrams으로 변환할 코드를 찾아 선택합니다.


  5. 선택한 클래스 또는 코드 파일을 UML Class Diagrams 디자이너로 드래그&드랍 합니다.


  6. 그럼 기존의 코드가 아래와 같이 UML Class Diagrams으로 변환이 완성되었습니다.

 

 

6.4. XMI 가져오기

XMI(XML Metadata Interchange)는 메타데이터를 통해 정보를 교환하기 위한 표준으로 XML 형식의 데이터를 사용합니다. 다양한 모델링 프레임워크나 도구에서 독자적인 포멧을 사용하지만 XMI 내보내기 등의 기능으로 다양한 모델링 도구에서 모델링 정보를 교환하거나 공유할 수 있습니다. (참고 http://en.wikipedia.org/wiki/.xmi)

이 표준 모델링 다이어그램의 XMI 를 Visual Studio에서 불러올 수 있는 기능을 제공합니다. XMI 파일을 가져오려면 다음과 같이 진행하시면 됩니다.

만약 사용할 수 있는 .XMI 파일이 없다면 다음의 전자정부 표준 프레임워크 사이트에서 샘플을 다운로드 받으실 수 있습니다. (http://open.egovframe.go.kr/scm/viewvc.php/trunk/DEV_IDE_PLUGIN/egovframework.dev.imp.codegen.modeltest/xmi_sample/sample.xmi?diff_format=s&logsort=cvs&sortby=log&view=markup&root=egovframedev)

 

  1. 아키텍처->Import XMI… 을 선택합니다.



  2. 확장명이 .XMI 인 파일을 찾아 선택한 후 확인을 클릭합니다.


  3. 가져온 XMI 요소의 형식을 확인하려면 아키텍처->창->UML 모델 탐색기를 선택합니다.


  4. UML 모델 탐색기에 XMI 파일에서 가져온 요소가 나타납니다.

 

 

6.5. Team Foundation 2010 연동

기존의 Visual Studio 모델링 프로젝트는 Team Foundation Server 작업 항목과의 연동을 이미 지원했습니다. 하지만 UML 다이어그램의 요소와 작업 항목과의 연결이나 관리 작업 부분에서 불편한 점이 있었습니다.

이번 Modeling Features Pack 은 Team Foundation Server와 연동하면서 바로 작업을 연결하거나 만들고, 또는 추적할 수 있는 부분이 강화되어 다이어그램과 작업 간의 관리가 훨씬 용이해 졌습니다.

 

6.5.1. 다이어그램의 요소와 작업 연결

모델링 프로젝트의 다이어그램의 모든 요소는 Team Foundation Server에 작업을 만들거나 연결할 수 있습니다. 가령, 모델리한 컴포넌트를 특정 개발자에게 작업을 할당하거나 그 작업의 진척율을 확인하고 보고를 받을 수 있습니다.

 

6.5.1.1. 모델링 프로젝트에서 작업을 만들려면?

  1. 먼저 작업과 연결할 모델링 다이어그램을 엽니다. 작업과 연결할 요소에 마우스 오른쪽 버튼을 클릭하여 작업 항목 만들기-><작업항목형식> 을 선택합니다.



  2. 작업 항목 만들기 화면에서 필요한 항목을 입력한 후 작업 항목 저장 버튼을 클릭합니다.



  3. Class Diagrams의 요소에 작업 항목이 연결되었음을 의미하는 아이콘이 표시되고, 요소의 속성 창에 1개의 작업 항목이 연결된 표시가 나타납니다.

 

6.5.1.2. 다이어그램 요소에 연결된 작업 항목을 보려면?

요소에 작업 항목이 연결이 되면 요소의 오른쪽 상단에 작업 항목이 연결되었음을 의미하는 아이콘이 표시됩니다. 이 아이콘이 표시된 다이어그램의 요소는 어떤 작업 항목이 연결되었는지 확인할 수 있습니다.

  1. 다이어그램 요소와 작업 항목이 연결된 요소에 마우스 오른쪽 버튼을 클릭하여 작업 항목 보기를 선택합니다.



  2. 다이어그램 요소와 연결된 작업 항목 목록이 나타납니다.

 

6.5.1.3. 다이어그램의 요소와 연결된 작업 항목을 제거하려면?

다이어그램의 요소와 연결된 작업 항목을 삭제하기 위해서 다음의 순서로 진행하십시오.

  1. 다이어그램 요소와 작업 항목이 연결된 요소에 마우스 오른쪽 버튼을 클릭하여 작업 항목 제거를 선택합니다.



  2. 작업 항목 제거 대화 상자에서 연결을 해제할 작업 항목의 체크 박스를 해지합니다. 체크 박스 해지 작업이 완료되면 확인을 클릭합니다.

     

  3. 다이어그램의 요소가 작업 항목에서 제거되어 작업 항목 연결을 의미하는 아이콘이 삭제된 것을 확인합니다.

 

6.6. Visual Studio Layer Diagram Extension

Visual Studio Modeling Features Pack은 Layer Diagrams의 유효성을 검사하거나 아키텍처 유효성을 검증하는 기능이 포함되어 있습니다. 이 Layer Diagrams의 유효성 검증과 명령 등을 확장하기 위해서 추가적인 Visual Studio SDK가 필요합니다.

이 단원은 [Visual Studio Modeling SDK] 단원을 참고 하십시오.

Posted by 땡초 POWERUMC

댓글을 달아 주세요