Parallel Patterns Library (PPL)

VC++ 10 Concurrency Runtime 2009. 8. 6. 06:00 Posted by 알 수 없는 사용자

이제 본격적으로 VC++ 10의 병렬 프로그래밍에 대한 이야기를 시작합니다.

첫 번째는 이름만 들어도 딱 '병렬 프로그래밍' 이라는느낌을 주고 가장 많이 사용될 것으로 생각하는 Parallel Patterns Library (PPL)입니다정말 이름에서 딱 느낌이 오죠 ^^



PPL은 크게 세 개의 features로 나누어집니다.

1. Task Parallelism : 병렬적으로 여러 가지 작업 처리

2. Parallel algorithms : 데이터 컬렉션을 제너릭 알고리즘으로병렬 처리

3. Parallel containers and objects :concurrent 접근이 가능한 제너릭 컨테이너

 


PPL 모델은 C++의 Standard Template Library(STL)과비슷합니다.

예를 들면 STL에는 for_each 라는 것이 있는데 PPL에는 이것의 병렬 버전인 parallel_for_each가 있습니다. 뒤에 설명하겠지만 parallel_for_each에 대해서 간단하게 말하면 array의 항목을 순회하는 parallel 알고리즘입니다.



PPL을 사용하기 위해서는 먼저 namespace Concurrency를 선언한 후 ppl.h 파일을 포함합니다.
........
#include <ppl.h>

using namespace Concurrency;
..............


먼저 parallel_for_each를 사용한 코드를 보여 드리겠습니다. parallel_for_each는 다음에 자세히 설명하겠으니 이번은 PPL 이라는 것이 어떻게 사용하는지만 아래 코드를 통해서 보세요^^

< 리스트 1. parallel_for_each 예제 >

#include <ppl.h>

#include <array>

#include <algorithm>

 

using namespace std;

using namespace std::tr1;

using namespace Concurrency;

 

int main()

{

   // Create anarray object that contains a few elements.

   array<int, 3> a = {13, 26, 39};

 

   // Use thefor_each algorithm to perform an operation on each element

   // of the arrayserially.

  for_each(a.begin(), a.end(), [&](int n) {

      // TODO:Perform some operation on n.

   });

 

   // Use theparallel_for_each algorithm to perform the same operation

   // in parallel.

  parallel_for_each(a.begin(), a.end(), [&](int n) {

      // TODO:Perform some operation on n.

   });

}


<리스트 1>의 코드를 보면 람다를 사용한 부분도 보이죠? 예전에 제가 C++0x의 새로운 기능에 의해 C++의 성능과 표현력이 향상 되었다고 이야기 했습니다. 이런 장점들이 PPL에 많은 기여를 하였습니다.




PPL과 OpenMP

예전에 PPL이 MSDN 매거진을 통해서 공개 되었을 때 많은 분들이 OpenMP와 비슷하게 보시고 왜 기존에 있는 것과 같은 것을 또 만드냐 라는 이야기를 하는 것을 들은 적이 있습니다.

PPL과 OpenMP는 같은 것이 아닙니다. 표현 방법이 얼핏 비슷하게 보일지 몰라도 개념이나 기반은 많이 다릅니다.

OpenMP는 pragma 지신문이고 PPL은 순수 C++ 템플릿으로 만들어진 라이브러리입니다.
그래서 PPL은 표현성과 유연성이 OpenMP에서 비해서 훨씬 더 뛰어납니다.
또한 PPL은 Concurrency Runtime 기반 위에 구축되므로 동일한 런타임을 기반으로 하는 다른 라이브러리와 잠재적 상호 운용성이 제공됩니다.

PPL은 어떤 것인지, 왜 OpenMP 보다 더 좋은지 이후에 제가 적을 글을 보면 쉽게 알 수 있으리라 생각합니다.


오늘은 PPL의 개념에 대한 이야기로 마치고 다음에는 PPL의 하나인 task에 대해서 이야기 하겠습니다.
시간 여유가 있거나 task에 대해서 빨리 알고 싶은 분들은 일전에 정재원님이 task 예제를 설명한 글을 올린 적이 있으니 먼저 그것을 보면서 예습을 하는 것도 좋습니다.



Concurrency Runtime

VC++ 10 Concurrency Runtime 2009. 7. 30. 06:00 Posted by 알 수 없는 사용자

VSTS 2010 VC++ 10의 큰 핵심 feature 두 가지를 뽑으라고 하면 저는 C++0x와 Concurrency Runtime 두 가지를 뽑고 싶습니다.

VC++ 10
은 시대의 변화에 맞추어 새로운 C++ 표준과 병렬 프로그래밍을 받아들였습니다.

현재도 Win32 API에 있는 Thread  관련 API를 사용하여 병렬 프로그래밍을 할수 있습니다. 하지만 이것만으로 병렬 프로그래밍을 하기에는 너무 불편합니다.
그래서 VC++ 10에는 Concurrency Runtime 이라는 것이 생겼습니다.



Concurrency
Parallel의 차이


Concurrency는 병행, Parallel은 병렬이라고 합니다.

Concurrency는 독립된 요구를 동시에 처리하고, Parallel은 하나의 task를 가능한 Concurrency로 실행할 수 있도록 분해하여 처리합니다.

< 그림 출처 : http://blogs.msdn.com/photos/hiroyuk/picture9341188.aspx >


VSTS 2010에서는 Concurrency는 런타임 용어 Paralell은 프로그래밍 모델 용어가 됩니다.
이를테면 프로그래밍 때에 분해하여 런타팀에 넘기면(이것이 병렬화), 런타임은 그것을 Parallel로 실행합니다. Concurrency Runtime은 Parallel 런타임으로 이해하면 될 것 같습니다.




Concurrency Runtime

< 그림 출처 : http://blogs.msdn.com/photos/hiroyuk/picture9341189.aspx >

Cuncurrency Runtime은 C++ 병행 프로그래밍 프레임워크입니다. Cuncurrency Runtime복잡한 parallel code 작성을 줄여주고, 간단하게 강력하고, 확장성 있고 응답성 좋은 parallel 애플리케이션을 만듭니다. 또한 공통 작업 스케줄러를 제공하며 이것은 work-stealing 알고리즘을 사용하여 프로세싱 리소스를 증가시켜 애플리케이션의 확장성을 높여줍니다.

 


Cuncurrency Runtime에 의해 다음의 이점을 얻을 수 있습니다.

1. data parallelism 향상 : Parallel algorithms은 컬럭션이나 데이터 모음을 복수의 프로세서를 사용하여 배분하여 처리합니다.

2. Task parallelism : Task objects는 프로세서 처리에 독립적으로 복수 개로 배분합니다.

3. Declarative data parallelism : Asynchronous agents와 메시지 전달로 어떻게 실행하지 몰라도 계산을 선언하면 실행됩니다.

4. Asynchrony : Asynchronous agents는 데이터에 어떤 일을 처리하는 동안 기다리게 합니다.

 

 

Cuncurrency Runtime 컴포넌트는 네 가지로 나누어집니다.

1. Parallel Patterns Library (PPL)

2. Asynchronous Agents Library (AAL)

3. work scheduler

4. resource manager

 

이 컴포넌트는 OS와 애플리케이션 사이에 위치합니다.


< 그림 출처 : MSDN >


Cuncurrency Runtime의 각 컴포넌트는 아래의 네 개의 헤더 파일과 관련 되어집니다.

컴포넌트

헤더 파일

Parallel Patterns Library (PPL)

ppl.h

Asynchronous Agents Library (AAL)

agents.h

Concurrency Runtime work scheduler

concrt.h

Concurrency Runtime resource manager

concrtrm.h

 

 

Concurrency Runtime을 사용하기 위해서는  namespace Concurrency를 선업합니다.

Concurrency RuntimeC Runtime Library (CRT)를 제공합니다.


Concurrency Runtime의 대부분의 type와 알고리즘은 C++의 템플릿으로 만들어졌습니다. 또한 이 프레임워크에는 C++0x의 새로운 기능이 많이 사용되었습니다.

대부분의 알고리즘은 파라메터 루틴을 가지고 작업을 실행합니다. 이 파라메터는 람다 함수, 함수 오브젝트, 함수 포인터입니다.



처음 들어보는 단어를 처음부터 막 나오기 시작해서 잘 이해가 안가는 분들이 있지 않을까 걱정이 되네요. 그래서 핵심만 한번 더 추려 보겠습니다.^^

1. Concurrency는 병행, Parallel은 병렬.
2. VSTS 2010에서는 Concurrency는 런타임 용어로 Paralell은 프로그래밍 모델 용어.
3. 프로그래밍 때에 분해하여 런타팀에 넘기면(이것이 병렬화), 런타임은 그것을 Parallel로 실행.
4. Cuncurrency Runtime은 C++ 병행 프로그래밍 프레임워크로 복잡한 parallel code 작성을 줄여주고, 간단하게 강력하고, 확장성 있고 응답성 좋은 parallel 애플리케이션을 만들수 있으며 공통 작업 스케줄러를 제공하며 이것은 work-stealing 알고리즘을 사용하여 프로세싱 리소스를 증가시켜 애플리케이션의 확장성을 높여준다.

5. Cuncurrency Runtime 컴포넌트는 네 가지로 나누어진다.

  1. Parallel Patterns Library (PPL)

  2. Asynchronous Agents Library (AAL)

  3. work scheduler

  4. resource manager



그럼 다음에는 Parallel Patterns Library(PPL)에 대해서 이야기 하겠습니다.^^





Visual Studio Extensibility 이야기

VSX(Visual Studio Extensibility) 는 Visual Studio 의 기능을 확장할 수 있는 SDK(Software Development Kit) 를 통해 툴의 기능을 확장할 수 있는 소프트웨어 개발 키트입니다. 잘 설계된 Visual Studio 의 확장 가능한 모델은 Visual Studio 2005 부터 비약적으로 발전했습니다. 그리하여 현재 Visual Studio 2010 은 MEF(Managed Extensibility Framework) 를 기반으로 하여 개발, 패키징, 배포에 이르러 훨씬 단순화된 새로운 확장 모델인 VSIX 를 내놓게 되었습니다.

Visual Studio 2003 부터 Visual Studio SDK 를 제공해 주었지만, Visual Studio 2003 버전에서는 확장 기능을 개발할 수 있는 그리 좋은 여건은 아니었습니다. 왜냐하면 Visual Studio 2003 의 Customizing Point 는 대부분 자동화 개체 모델인 DTE 에 굉장히 의존적이었습니다.

Visual Studio 2005 는 이전의 IDE 기반을 갈아엎었다고 할 수 있을 정도로 상당히 파격적인 모습으로 다가왔습니다. 사실 이때만해도 Visual Studio 2003 에 비해 너무 느려지지 않았냐는 불만을 상당히 많이 들었습니다. 하지만 개발자들의 하드웨어 스팩이 좋아지고, Visual Studio 2005 가 제공하는 다양한 기능은 안쓸래야 안쓸수 없었답니다. 그리고 Visual Studio 2005 SDK 는 2008 버전까지 고스란히 답습하고 있었습니다.

Visual Studio 2008 은 이제 .NET 개발의 국민 IDE 로 자리매김 하였습니다. 그리고 빠르게 많은 기업에서 Visual Studio 2008 과 .NET Framework 3.5 기반으로 마이그레이션을 하고 있습니다. (적어도 제 주변 대부분이..) 그리고 이 시점부터 Software Factories 개념을 도입한 Guidance Automation 과 Blueprints 등 Visual Studio 확장 기능들이 대거 모습을 드러내기 시작했습니다. (GA 는 2005 버전부터 등장했지만 실제 활성화된 시점은 개인적으로 2008 부터가 아닐까 생각합니다)

그렇다면 Visual Studio 2010… 이제는 IDE 환경의 지존을 논한다고 생각합니다. 광고성 멘트라고 생각하시면 그냥 스킵 하셔도 좋습니다. .NET Framework 는 더없이 탄탄해지고, 딱딱했던 IDE 환경은 UX 친화적인 면을 보여주기 위해 노력한 흔적이 엿보입니다. 그리고 Oslo, Velocity, Pex, T4 Templates, 미려해진 DSL Tools, 진정한 통합을 꿈꾸는 Team System, 그리고 이번 주제였던 정말 편한 개발 환경 확장을 제공해주는 VSX...

   

.NET 의 과거와 현재, 그리고 미래
http://blog.powerumc.kr/172

[T4] - 1. Code Generation 과 GA(Guidance AUtomation)
[.NET/Visual Studio] - [T4] - 1. Code Generation 과 GA(Guidance Automation)


[Blueprints] S+S Blueprints
[Software Development/Software Factory] - [Blueprints] S+S Blueprints

   

Visual Studio Extensibility 종류

그럼 기존의 VSX 는 어떻게 IDE 도구를 확장하였을까요?

  • Visual Studio Macro
    VB 스크립트 언어를 이용하여 Visual Studio 의 자동화 개체 모델의 DTE 객체를 제어할 수 있습니다. 아무래도 스크립트 언어이다보니 개발의 편의성은 좋지만 배포와 코드 보안에 좀 떨뜨름합니다.

       

  • Visual Studio Addin
    기능적인 면에서 Visual Studio Macro 와 큰 차이는 없습니다만, 스크립트 언어가 아닌 C# 과 같은 Managed 언어로 개발이 가능합니다. 태생적으로 Visual Studio Macro 와 동일선상이기 때문에 Addin 의 독립적인 기능만으로는 확장에 한계는 있었습니다. 하지만, DTE 개체 모델을 통해 개발이 굉장히 쉽고, 배포 또한 단순하여 가장 많은 사랑을 받은 VSX 분야입니다.

       

  • Visual Studio Integration Package (이하 VSIP)
    Visual Studio 를 진정으로 통합할 수 있는 확장 방법입니다. Visual Studio 의 COM Interface 를 고스란히 사용할 수 있고, 이것을 이용하여 Visual Studio 의 모든 기능을 활용하고 확장할 수 있습니다. 실제로 Visual Studio 기능의 대부분이 VSIP 를 통해 개발이 되었고 Visual Studio 의 특징을 가장 잘 보여주는 Interface 들로 구성이 되어있습니다. 여러분이 잘 알고 있는 솔루션 탐색기, 오류 리스트, 팀 탐색기 등 셀 수 없을 정도의 많은 VSIP 들이 Visual Studio 에 포함되어 있습니다.

       

  • Visual Studio Shell Isolated
    Visual Studio Shell Isolated 는 Visual Studio 와 같은 Shell 을 제공하고 개발할 수 있는 방법입니다. VSIP 가 Visual Studio 확장 기능에 필요한 요소를 가르킨다면, Shell Isolated 는 VSIP 를 담는 그릇이 되겠군요. Visual Studio Shell Isolated 를 이용하게 되면 기존에 Visual Studio 에서 제공하는 여러 가지 인터페이스를 고스란히 사용할 수 있는 이점이 있습니다. 가량, Project Type, Intellisence 와 Microsoft 의 통합 빌드 솔루션인 MSBuild 등 다양한 기능을 곧바로 사용할 수 있다는 장점이 있는 것이죠.

       

  • Visual Studio Language Package
    Visual Studio 에서 사용할 수 있는 언어를 개발할 수 있습니다. 기본적으로 C#, VB.NET, C++ 등을 사용할 수 있지만 PHP, RoR, Native C 등의 언어를 개발할 수 있도록 하고, 이미 Visual Studio for PHP, Visual Studio for RoR 가 상용화 되었고, Visual Studio for C 는 Visual Studio SDK 예제로도 포함이 되어 있답니다.


       
  • Domain-Specific Language Package
    도메인에 특화된 언어를 개발할 수 있는 방법을 제공합니다. 일반적으로 IT 조직과 개발 조직은 서로가 사용하는 언어가 다릅니다. 즉, 경영진과 실무진과 같은 물과 기름의 관계를 이해시키기 위한 언어로써, 이미 Visual Studio 에서 광범위하게 사용되고 있는 방법입니다.

 

  • Help Integration
    MS HELP 2.0 을 이용하여 Microsoft Document Explorer 의 콘텐츠를 추가할 수 있는 방법입니다. Microsoft Document Explorer 는 일반적으로 Visual Studio 도움말로 생각하시면 됩니다. 이곳에 콘텐츠를 추가하기 위해 Setup Wizard 를 제공하고, 쉽게 Visual Studio 도움말에 자사 또는 자신의 콘텐츠를 추가할 수 있습니다.

       

어휴,, 정말 다양한 방법으로 Visual Studio 를 확장하는 방법을 제공해 주는군요. 이러한 아키텍처는 Visual Studio 2005 부터 제대로 뿌리를 내렸는데, 그 중 일부분은 Visual Studio 2010 에서 좀 더 획기적으로 변신을 합니다.

변신을 하면서 기존의 COM 기반의 인터페이스는 더 이상 WPF 기반의 어플리케이션에서 상당수 비호환적인 면이 있고, 한계점을 드러내지 않았나 생각을 해봅니다. 실제로 기존의 인터페이스는 WPF 의 Managed 환경에서 더 이상 호환할 수 없어집니다. WPF 기반의 IDE 환경에서는 새로운 인터페이스가 필요했고, MEF 를 도입함으로써 새로운 확장 가능한 모델이 필요했습니다. 바로 그것이 새로운 확장 가능한 모델인 VSIX 입니다.

VSIX 는 기존의 IDE 확장 모델과 새로운 MEF 기반의 확장 기능을 개발부터 패키징, 배포까지 통합할 수 있는 방법을 제공해 줍니다. 뿐만 아니라 기존의 확장 기능과 새로운 MEF 기반의 확장 기능을 통합하고 연동까지 할 수 있으니 이것이야 말로 누이 좋고 매부 좋은 일이 아닐까 합니다.

   

이제부터 위의 다양한 확장 기능을 개발하는 방법을 시작하여 VSIX 에 이르기 까지 한번 짚고 넘어가볼 예정입니다. 아직까지 국내에서는 이러한 희귀한 분야를 다루는 곳도 흔치 않고, 관심이 있더라도 정보가 부족하여 어느 정도 종점을 찍고 포기하는 분들도 많이 있습니다. 아마 이 연재를 통해서 Visual Studio 에 보다 관심을 갖고 널리 기술을 알리는 좋은 기회가 되지 않을까 생각을 하면서, 연재를 기대해 주세요.

VSTS 2010 팀 맴버 추가 모집

VSTS 2010 팀 블로그 2009. 7. 27. 09:33 Posted by POWERUMC

저희 VSTS 2010 팀은 차세대 개발 플랫폼인 Visual Studio 2010, Visual Studio Team System 2010, C# 4.0, C++ 0x, Cloud 등을 공부하고 다양한 매체를 통해 알리는 팀 입니다.

저희 VSTS 2010 팀은 이번 분기를 기점으로 보다 세분화하고 다양한 활동을 하기 위해 팀 맴버를 추가로 모집하고 있습니다.


   

활동 영역

온라인 활동 영역

팀 블로그 활동

팀 블로그를 통해 자신의 글을 게시할 수 있습니다. 현재 수백 명의 정기 구독자에게 글이 공개가 되며, 팀 블로그가 구글 등의 검색 상위권에 이르게 됨으로 자신의 글이 상위 검색에 노출되는 간접적인 혜택을 누릴 수 있습니다.

온라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 여러 가지 온라인 세미나의 스피커로 활동하게 됩니다.

온라인 커뮤니티(예정)

온라인 커뮤니티 활동과 함께 커뮤니티 운영 활동을 하게 됩니다.

   

오프라인 활동 영역

오프라인 스터디

오프라인 스터디를 통해 자신의 분야를 공부하고 발표합니다. 그리고 좋은 콘텐츠는 곧바로 온라인/오프라인 세미나 스피커 활동으로 이어집니다.

오프라인 세미나

한국 마이크로소프트와 팀 자체에서 진행하는 오프라인 세미나의 스피커로 활동할 수 있습니다. 팀 자체에서는 매월 오프라인 정기 세미나를 진행하며, 자신의 노하우를 오프라인 세미나를 통해 전달할 수 있는 기회를 드립니다.

기고

팀 블로그를 통해 축적된 자신의 콘텐츠는 월간 잡지 등에 기고할 수 있습니다.

책 집필, 번역(예정)

다양한 노하우를 책으로 집필하고, 외국의 유명 서적을 번역하는 활동을 계획하고 있습니다.

Microsoft MVP 추천

MVP 에 되고자 하시는 분은 한국 이크로소프트 직원과 마이크로소프트 MVP 의 추천을 드립니다.

   

모집 분야

  • Cloud Development
  • Parallel Development
  • Web Development
  • Windows 7 Development
  • RIA Development
  • Architect Development
  • Office Business Application Development
  • .NET Framework 4.0
  • Visual Studio 2010
  • Visual Studio Team System 2010
  • ETC…

   

마감

이번 분기는 단순한 스터디를 뛰어 넘는 다양한 활동을 계획하고 있습니다. 그러므로 특별히 마감 일자는 없습니다.

조만간 저희 팀에서 워크샵을 갈 예정인데, 그 전에 함께 워크샵을 가면 좋겠네요.

   

지원 방법

아래의 양식을 채워주시고 umc골뱅이dotnetxpert.com 으로 보내주세요.

이름

  

나이

  

블로그

  

전화번호

  

티스토리 아이디

  

소개

(직업 및 회사명 포함)

관심 분야

(중복 가능)

   

   

지원 시 유의 사항

참고로 저희 스터디에서는 배우고자 지원하시는 분들은 선발하지 않습니다. 저희 팀의 스터디에서는 여러분들에게 아무것도 가르쳐주지 않습니다.

저희 팀에서는 절대 실력을 보고 맴버를 선발하지 않습니다. 물론 실력이 출중하면 좋겠지만 새로운 VSTS 2010 분야는 어느 누구도 밟아보지 않은 새로운 황야와 같습니다. 새로운 길을 함께 가실 활동력이 충분하신 분들은 꼭 지원해 주시기 바랍니다. ^^

몽당연필과 함께하는 VSTS 2010 모델링 0/4

Architect Development 2009. 7. 22. 09:39 Posted by 알 수 없는 사용자
Architect Development 의 시작은 무엇일까 생각하다가 우선 모델링 관련 부분부터 해야 겠다는 마음으로 이글을 작성하게 되었습니다. 이 글을 시작하기 전 우선 글의 성격은 Architect Development 개발의 시작으로 모델링 기반의 개발이 좋을 것 같고, 제 나름대로 프로젝트를 해 보니 문서를 기반으로 프로젝트를 시작하고 개발자들과 문서를 보면서 개발 회의를 하는 것과 또는 강의 할 때 실제 프로그램이 돌아가는 것을 보고 난 다음에 모델링 도구를 이용하여 프로그램이 운영되고 있는 영억이나 구조를 설명하면 개발자분이나 교육을 듣는 분들이 이해를 빠르게 했기 때문입니다.

그럼. 첫 시작으로 모델링을 선택하고 UML 기반의 모델링을 소개하는 것은 일반적으로 학교에서 UML은 어느 정도 접하고 졸업한 개발자분들도 있고, 개발을 오래 하다보면 UML 로 그린 다어이그램들을 보신 경우가 많기 때문입니다. 처음 발표된 VSTS 2005 는 UML이 아니라 다른 기반의 모델 기반 개발을 지원 했습니다. 저는 Visual Studio 2005에 처음 접하였지만, 그 전에는 UML을 Visio로 그리고 실 개발을 Visual Stduio 2003으로 했습니다. 개발할 때 설계를 봤을 까요? 제가 솔직히 이야기 하면 저도 100% 다 보지 않고 요구사항이 변경되거나 구조가 변경되면 먼저 코드를 작성하고 추후 Visio로 변경해야지 하는 마음만 먹고 하지 않았습니다.

VSTS의 새로운 제품은 이제 그렇지 않지 않아도 됩니다.

VSTS 2010의 Architect 부분에서는 UML을 지원하고 이 모든것이 TFS 제품과 연관이 됩니다. 개발자는 이를 확인하고 실 개발에 반영하거나 반영된 것을 아키텍처가 변경하거나 개발자가 바로 변경할 수도 있다는 것입니다.

이런 이유로 제가 첫번째 모델링을 이야기 하고 모델 기반 개발에 대하여 소개하도록 하겠습니다.

PS. 전 모델 기반 개발이 선택이 아닌 필수로 생각합니다. 그렇지 않으면?? ㅎㅎ 추후 글로..
이제 시작입니다.

Architect Development ?

Architect Development 2009. 7. 21. 18:04 Posted by 알 수 없는 사용자


Architect Development 을 위하여 무엇을 해야 할가요?
아니 Architect Development 이란 영역은?

우리가 흔히 개발을 한다고 하면 보통 요구사항 분석, 설계, 개발, 테스트 및 디버깅, 배포를 끝으로 그 다음 유지보수를 합니다. 유지보수에서는 개발, 테스트 및 디버깅 재배포 등의 단계를 거치게 됩니다.
그렇다면 여기서 앞 부분은 요구사항 분석, 설계 부분은 유지보수에서 빠지는 것일까요?

답은 " 아닙니다 " 겠죠? 그렇다면 요구사항 분석, 설계 부분이 빠지는 이유는 개발이 완료되고 배포되어 사용자가 사용하고 있는 중에 문제가 오류가 발생하여 개발자 분들이 수정하고 다시 테스팅 및 디버깅 후 배포하는 것입니다. 프로그램이 사용중에 오류가 발생하지 않고 고객 또는 사용자가 새로운 기능을 요구하였을 경우에는 어떻게 할까요?

여기서 옛날에 했던 요구사항 분석, 설계 부분을 돌아보게 됩니다. 그러면, 제가 지금까지 보아온 회사 중에서는 설계가 잘되어 있고, 요구사항 분석도 잘 되어 있어 모든 것이 일사 천리로 일이 진행 된것을 볼 수 있었습니다. 그렇지 않은 회사를 보면 어떻게 될지는 이 글을 읽는 개발자 분들이 더 잘 아실거라 생각합니다. 그럼 아키텍쳐 개발은?

아키텍처란 용어는 영한 사전에서보면  일반적으로 "건축, 천축술, 천축 양식, 구조"라고 번역합니다. 그렇다면국어사전은? 기능 면에서 본 컴퓨터의 구성방식이라고 설명합니다.(네이버 국어사전 참조) 여기서 아키텍쳐란 구조, 구성이라는 용어로 한번 보겠습니다.

구조, 저희가 개발하는 시스템에 대한 정확인 요구사항에 맞는 분석과 이를 기반으로 정확한 구조, 구성이 된 설계가 있다면 어떨까요? 이 설계의 기본적인 구조는 Windows 플랫폼에 PHP 개발, 아니면 ASP.NET 개발등으로 예를 들어 보고, 기본적인 구조를 정확히 정의하고 이를 표현할 수 있으며, 많이 사용하는 방법으로 표시하여 개발자들과 협업, 의사 소통이 이루어 질 수 있다면 어떨까요?

전 이 해답을 Visual Studio Team System(VSTS) 에서 찾았다고 생각합니다. 제가 MS 쪽 제품 중에 VSTS를 좋아하는 이유 중에 바로 Architect Development이 가능하게 해준다는 것입니다. 다른 제품 쪽도 있고 저 역시 다른 사이트에서 많은 자료를 봅니다.(다른 사이트의 Meet the Experts등 여러 사이트가 있습니다. 단 영어 입니다 ㅠ.ㅠ)

옛날 VSTS는 업계가 많이 사용하는 UML를 지원하지 않고 다른 모델링 도구등을 이용한 설계를 할 수 있도록 했습니다. 기능은 매우 훌륭했지만... 많은 사용자가 이것을 사용했을까 하는 것입니다. 지금은?

VSTS 에서도 이제 UML도 지원한다..

그럼? 네 Visio 같은 도구로 그림을 그리는 것이 줄어들었다는 것입니다. 그리고 VSTS에 통합되므로써 개발자들과의 의사소통, 협업이 가능하다는 것이 매우 좋아졌다는 겁니다. 프로젝트에서 대부분 아키텍쳐는 무시되고 요구사항이 수시로 바뀌는 등등 매우 많은 일들이 생겨나는데 이것을 대응할 수 있다는 것입니다.
업계에서 많이 사용하는 UML은 학교에서 S/W를 전공한 사람은 모두 한번씩 배웠던 것이고, 이를 이용하여 개발자들과 협업을 통해 고객의 요구사항을 능동적으로 대처할 수 있고, 실제 설계에 반영할 수 있습니다.

이런 매우 좋아진 이 VSTS 2010에 대하여 이제 부터 제가 하나씩 하나씩 알아보고 여러 분들에게 소개를 하겠습니다. ^^ 다음 은 그럼?? VSTS 2010의 모델링 개발에 대하여 이야기 하겠습니다.

MEF Preview 6 공개

Managed Extensibility Framework 2009. 7. 20. 12:36 Posted by POWERUMC

MEF(Managed Extensibility Framework) 이 2009년 7월 13일에 릴리즈되어 14일에 공개가 되었습니다. 특히 MEF 는 .NET Framework 4.0 에 포함이 되어있으며, CodePlex 에서 굉장히 빠른 속도로 발전하고 있는 프레임워크 중에 하나 입니다.    

CodePlex MEF 사이트에 등록된 릴리즈 노트 입니다.

그 중에서 몇 가지만 살펴보도록 하겠습니다.

실버라이트 3 지원

특히 이번에 눈여겨 볼 만한 것이 Silverlight 3 를 지원하는 것입니다. 이미 Preview 5 이전의 MEF 에서는 실버라이트를 지원하기 위해 코드에서 전처리 명령 구문을 사용하여 프레임워크 실버라이트가 지원되긴 했습니다. 그것을 기반으로 이번 Preview 6 버전에서는 실버라이트 3 용 솔루션이 제공됩니다. 이 솔루션을 통해 실버라이트용 MEF 프레임워크를 빌드 하시면 됩니다.

   

ExportAttribute 의 seal 키워드 제거

이번 MEF Preview 6 에서 ExportAttribute 의 seal 키워드가 제거됩니다. 이 전 Preview 5 에서는 ExportAttribute 을 절대 상속할 수 없는 구조였기 때문에 독자적인 Export 를 제공할 수 없었기, Metadata 를 ExportAttribute 와 같은 기능울 개별적으로 지정해야 하는 등의 Export 기능의 확장에 불합리한 구조로 되어있었습니다. 하지만 이번 Preview 6 버전에서는 ExportAttribute 클래스의 seal 키워드가 제거 됨으로써 ExportAttribute 의 확장이 용이하게 되었습니다.

 

ImportMany 로 통일된 컬렉션 처리

이제 모든 컬렉션은 ImportMany 로 통일되었습니다. Preview 5 에서는 ExportCollection<T> 또는 IEnumerable<T> 와 같이 사용하기도 까다롭고 이것으로 반환된 객체를 처리하기에도 편리한 구조는 아니였습니다. Preview 5 에서도 ImportMany 의 기능이 존재하였지만, 이번 Preview 6 는 이것으로 모든 컬렉션 처리를 하도록 통일되었다는게 혼란스러웠던 부분을 간소화할 수 있을 것 같습니다.

   

기타 그 밖에도 구조적으로 보다 안정되었고, 메서드나 클래스의 네이밍이 변경되었고, 예외 시에 Composition 동작의 분석을 추적하기 쉽도록 덤프(Dump) 를 뜰 수 있는 로깅 기능 등 다양한 기능이 추가되었습니다. 정식 버전의 MEF 는 어떤 모습으로 나올지 정말 기대가 됩니다. 더 자세한 내용은 아래의 링크를 통해 더 쉽게 설명이 되어있으니 참고 하십시오.


참고문헌
MEF Preview 6 Available
http://blogs.msdn.com/nblumhardt/archive/2009/07/09/mef-preview-6-available.aspx

 

 

지난 6월 10일 VSTS 2010 팀에서 진행한 MEF(Managed Extensibility Framework) 세미나에서 보여드린 데모를 조금 수정하여 Visual Studio Gallery 에 공개하였습니다.

Visual Studio 2010 이 WPF 기반의 IDE 환경으로 탈바꿈하면서 특히 코드 에디터 쪽은 WPF 의 기능을 유감없이 보여주었습니다. 특히 코드 에디터는 MEF 를 통해 대부분의 기능이 만들어졌고, 이것을 확장할 수 있는 기능을 만드는 것이 얼마나 편해졌는지 보여주기 위한 데모였습니다.

세미나에서도 설명했지만 현재 Visual Studio 2008 까지 버전에서 이러한 확장 기능을 개발하기 위해서는 굉장히 많은 단계를 거쳐야 합니다. Visual Studio 2008 까지는 COM 을 기반으로 한 IDE 이기 때문에 적용되는 기술만 나열해도 절대 단순하지 않은 과정을 거쳐야 합니다. 마우스와 키보드와 같은 장치의 이벤트를 핸들링 해야 하고, GDI+ 를 이용해 화면에 드로잉을 하고 잔상과 깜빡임을 없애기 위해 더블 버퍼링 등의 기법이 조합되어야 했습니다. 그리고 나은 사용자 인터페이스를 위해 많은 기교를 부려야만 했죠.

   

멀리서 프레젠테이션을 시청하는 분들도 커서의 위치를 잘 보이도록 화살표가 커서를 따라 다닙니다. 
 

 

Visual Studio Gallery

Umc.Core.Tools.MousePresentationTracker.v1.0

   

   

현재는 단순하게 마우스를 따라다니는 데모를 급 개조했지만, 나중에는 생각해 놓은 기능들을 추가하려고 합니다. 어쨌든 이전에 공개했던 VSGesture 와 다른 컨셉으로 프레젠테이션을 위한 도구로 점차 기능이 추가될 예정입니다.

PPL task를 이용한 피보나치 수 계산

VC++ 10 Concurrency Runtime 2009. 7. 17. 00:43 Posted by 알 수 없는 사용자
오래만에 돌아왔습니다.

동영상 자막 번역은 영 아니다라는 판단하에(?), 일반적인 형식으로 C++0xVisual Studio 2010에서의 병렬 프로그래밍에 대해 글을 써볼 생각입니다.

일단 http://code.msdn.microsoft.com/concrtextras 에서 샘플 코드를 받으십시오. 그를 기준으로 당분간은 진행 예정입니다. 당연히 돌려보려면 Visual Studio 2010 베타1이 필요합니다.

오늘은 Parallel Patterns Library를 이용한 피보나치 수 계산 예부터 살펴보죠. 순차 수행 버전과 PPL의 태스크 기능을 이용한 병렬 수행 버전의 성능 비교가 첫번째 핵심 사항입니다. 그리고 malloc 대 Concurrency::Alloc의 성능 비교가 두번째 핵심 사항 되겠습니다.

소스를 찬찬히 살펴보죠.

    8 #include "windows.h"

    9 #include <ppl.h>

   10 

   11 using namespace Concurrency;

   12 

   13 int SPINCOUNT = 25;

   14 

   15 //Spins for a fixed number of loops

   16 #pragma optimize("", off)

   17 void delay()

   18 {

   19     for(int i=0;i < SPINCOUNT;++i);

   20 };

   21 #pragma optimize("", on)


먼저 헤더 파일 포함이 나오고, 각 작업의 계산 부하 조절을 위한 idle loop 함수가 나옵니다. pragma 디렉티브로 최적화를 해당 함수에 대해서만 끄고 있습니다. 그래야 실제 부하 조절 용도로 의미가 있겠죠.

   23 //Times execution of a functor in ms

   24 template <class Functor>

   25 __int64 time_call(Functor& fn)

   26 {

   27     __int64 begin, end;

   28     begin = GetTickCount();

   29     fn();

   30     end = GetTickCount();

   31     return end - begin;

   32 };


이 함수는 단순히 프로파일링(성능 측정)을 위한 유틸리티 함수 되겠습니다.

   34 //Computes the fibonacci number of 'n' serially

   35 int fib(int n)

   36 {

   37     delay();

   38     if (n< 2)

   39         return n;

   40     int n1, n2

   41     n1 = fib(n-1);

   42     n2 = fib(n-2);

   43     return n1 + n2;

   44 }


실제 가장 이해하기 쉬운 재귀 방식의 피보나치 수 구하기 함수입니다. 당연히 이 방식은 중복 계산이 많아 성능이 한참 떨어지게 되는데요, 이 글의 쟁점은 아니므로 넘어갑니다.

   45 //Computes the fibonacci number of 'n' in parallel

   46 int struct_fib(int n)

   47 {

   48     delay();

   49     if (n< 2)

   50         return n;

   51     int n1, n2;

   52 

   53     //declare a structured task group

   54     structured_task_group tasks;

   55 

   56     //invoke the first half as a task

   57     auto task1 = make_task([&n1,n]{n1 = struct_fib(n-1);});

   58     tasks.run(task1);

   59 

   60     //run the second recursive call inline

   61     n2 = struct_fib(n-2);

   62 

   63     //wait for completion

   64     tasks.wait();

   65 

   66     return n1 + n2;

   67 }


다음은 해당 알고리즘의 병렬 구현입니다. structured_task_group 변수를 하나 선언하고, make_task를 이용해 재귀 호출의 한쪽을 담당할 태스크를 만든 뒤, 태스크 그룹을 통해 돌립니다. tasks.wait() 호출을 통해 스폰한 태스크 작업이 마무리될 때까지 대기한 후, 최종 결과를 리턴하고 있습니다. C++0x의 람다가 쓰이고 있는 것을 확인하실 수 있습니다.
재귀적으로 호출이 되면서 꽤나 많은 태스크들이 만들어질텐데, 그냥 스레드 수준에서 직접 이런 작업을 했다면, 실제 하드웨어가 지원하는 병렬 수행의 수보다 과도하게 많은 스레드 생성이 이루어지면서, 상당히 비효율적으로 돌텐데요. PPL의 태스크 개념을 사용해 이렇게 보다 고수준에서 작업하면 그러한 오버헤드를 상당 부분 알아서 최적화 해줍니다.

   69 //Computes the fibonacci number of 'n' allocating storage for integers on heap

   70 int struct_fib_heap(int n)

   71 {

   72     delay();

   73     if (n< 2)

   74         return n;

   75     //n1 and n2 are now allocated on the heap

   76     int* n1;

   77     int* n2;

   78 

   79     //declare a task_group

   80     structured_task_group tg

   81 

   82     auto t1 = make_task([&]{

   83         n1 = (int*) malloc(sizeof(int));

   84         *n1 = struct_fib_heap(n-1);

   85     });

   86     tg.run(t1);

   87     n2 = (int*) malloc(sizeof(int));

   88     *n2 = struct_fib_heap(n-2);

   89     tg.wait();

   90     int result = *n1 + *n2;

   91     free(n1);

   92     free(n2);

   93     return result;

   94 }


malloc으로 힙에 버퍼를 잡아 결과를 리턴하는 버전입니다. Concurrency::Alloc과의 성능 비교를 위한 함수 되겠습니다.

   95 //Computes the fibonacci number of 'n' using the ConcRT suballocator

   96 int struct_fib_concrt_heap(int n)

   97 {

   98     delay();

   99     if (n< 2)

  100         return n;

  101     int* n1;

  102     int* n2;

  103     structured_task_group tg

  104     auto t1 = make_task([&]{

  105         n1 = (int*) Concurrency::Alloc(sizeof(int));

  106         *n1 = struct_fib_concrt_heap(n-1);

  107     });

  108     tg.run(t1);

  109     n2 = (int*) Concurrency::Alloc(sizeof(int));

  110     *n2 = struct_fib_concrt_heap(n-2);

  111     tg.wait();

  112     int result = *n1 + *n2;

  113     Concurrency::Free(n1);

  114     Concurrency::Free(n2);

  115     return result;

  116 }


이번에는 병렬 런타임의 suballocator를 이용하고 있습니다.

  117 int main()

  118 {

  119     int num = 30;

  120     SPINCOUNT = 500;

  121     double serial, parallel;

  122 

  123     //compare the timing of serial vs parallel fibonacci

  124     printf("computing fibonacci of %d serial vs parallel\n",num);

  125     printf("\tserial:   ");

  126     serial= (double)time_call([=](){fib(num);});

  127     printf("%4.0f ms\n",serial);

  128 

  129     printf("\tparallel: ");

  130     parallel = (double)time_call([=](){struct_fib(num);});

  131     printf("%4.0f ms\n",parallel);

  132 

  133     printf("\tspeedup: %4.2fX\n",serial/parallel);

  134 

  135     //compare the timing of malloc vs Concurrency::Alloc,

  136     //where we expect to get speedups because there are a large

  137     //number of small malloc and frees.

  138 

  139     //increase the number of tasks

  140     num = 34;

  141 

  142     //reduce the amount of 'work' in each task

  143     SPINCOUNT = 0;

  144 

  145     //execute fib using new & delete

  146     printf("computing fibonacci of %d using heap\n",num);

  147     printf("\tusing malloc:             ");

  148     serial= (double)time_call([=](){struct_fib_heap(num);});

  149     printf("%4.0f ms\n",serial);

  150 

  151     //execute fib using the concurrent suballocator

  152     printf("\tusing Concurrency::Alloc: ");

  153     parallel = (double)time_call([=](){struct_fib_concrt_heap(num);});

  154     printf("%4.0f ms\n",parallel);

  155 

  156     printf("\tspeedup: %4.2fX\n",serial/parallel);

  157 

  158     return 0;

  159 }


마지막으로  main 함수입니다. 단순히 각 함수를 호출하고 시간을 측정한 뒤 적절한 메시지를 출력하고 있습니다. 역시 람다가 쓰여 구문이 간결해졌습니다.

2 코어 머신에서 디버그 버전으로 돌려본 결과는 다음과 같습니다.


순차 대 병렬 버전의 경우 1.29배 속도 향상, malloc 대 Concurrency::Alloc의 경우 2.60배 속도 향상을 확인할 수 있습니다. 병렬 버전에서의 속도 향상이 생각보다 미미한데요. 제 컴퓨터가 좀 문제(?)가 있어서 그럴지도 모르겠습니다; 한편, 병렬 환경에서 메모리 할당 및 해제가 빈번한 경우, 반드시 병렬 런타임의 할당자를 써야겠군요.


추가: 제 블로그에 관련 주제로 글(두가지 C++ 차세대 병렬 플랫폼 간단 비교)을 하나 올렸습니다. 참고하세요. ^^

Welcome to F#(12) - 공동작업 좋치아니항가

F# 2009. 7. 16. 14:38 Posted by 알 수 없는 사용자

- F#의 첫 라이브러리 출연(Feat. C#)

오늘은 간단하게, F#에서 만든 코드를 C#에서 사용해보는 시간을 갖겠습니다. 자~ 간단하게 간단하게~.

우선, C#으로 콘솔프로그래밍 프로젝트를 하나 생성하고 같은 솔루션에 F# 라이브러리 프로젝트를 하나 추가합니다. 대략 아래와 같은 모양이 됩니다. 



그리고 Module1.fs에다가 아래의 코드를 작성합니다. 


 module FirstModule =
    type Type1 =
        { num: int }
        member self.reverse = { num = -self.num }
        member self.add(num2) = { num = self.num + num2 }
       
type Type2 =
    { num: int }
    member self.reverse = { num = -self.num }
    member self.add(num2) = { num = self.num + num2 }

let add5 num = num + 5



FirstModule라는 모듈을 선언하고 그 안에 Type1이라는 타입을 선언한 걸 보여주고 있습니다. 그리고 Type1의 멤버로는 int타입의 num이 있고 reverse, add라는 함수가 있습니다. 각각의 함수뒤의 {}안의 코드는 num에 새로운 값을 할당해서 Type1의 새로운 객체를 리턴하는 내용으로 보시면 이해가 되실 겁니다. 그리고 그 아래에는 모듈선언없이 그냥 Type2라는 타입을 선언했구요, 그 밑에는 함수 add5를 선언했습니다. 이런 코드들을 C#에서 참조한다면 어떻게 쓸 수 있을까요? 

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CoWorkWithFSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            Module1.FirstModule.Type1 type1 = new Module1.FirstModule.Type1(5);
            Module1.FirstModule.Type1 type1_2 = type1.reverse;

            Console.WriteLine(type1_2.num);

            Module1.Type2 type2 = new Module1.Type2(6);
            Module1.Type2 type2_2 = type2.add(9);

            Console.WriteLine(type2_2.num);

            Console.WriteLine(Module1.add5(12));
        }
    }
}



위 코드를 보시면, Module1이라는 파일이름이 가장 먼저 오는 걸 볼 수 있습니다. 파일이름자체가 모듈이 되는거죠. 베타1이라서 그런지는 모르겠지만, F#으로 만든 코드는 "using Module1;" 형태로 using을 할 수 없었습니다. 에러메세지를 보면 네임스페이스가 아니라서 안된다고 하니 모듈도 클래스로 취급이 되는거 같은데 개선이 될지 아니면, 이대로 남을지 모르겠네요. 코드를 보시면 알겠지만, 매번 모듈명을 반복해서 적어줘야 하니 좀 빡세긴 합니다만;;;; 

아무튼, 저렇게 F#에서 작성한 타입의 객체를 생성할 수 있구요, 멤버 메서드와 함수를 호출할 수도 있습니다. 다만, 함수의 결과로 새로운 객체가 생성된다는 점 기억하시구요. 실행결과는 아래와 같습니다. 



그러면, 지난주에 만들었던 Discriminated Union을 이용한 간단한 사칙연산 코드를 C#에서 사용해보도록 하겠습니다. 아래코드를 Module1.fs에 추가하구요 

type Expr =
    | Num of float
    | Add of Expr * Expr
    | Sub of Expr * Expr
    | Mul of Expr * Expr
    | Div of Expr * Expr

let rec Calc expr =
    match expr with
    | Num num -> num
    | Add (e1, e2) -> (Calc e1) + (Calc e2)
    | Sub (e1, e2) -> (Calc e1) - (Calc e2)
    | Mul (e1, e2) -> (Calc e1) * (Calc e2)
    | Div (e1, e2) -> (Calc e1) / (Calc e2)



아래 코드를 C#코드에 추가해줍니다. 

 Module1.Expr expr = new Module1.Expr._Mul(
    Module1.Expr.Add(
        Module1.Expr.Num(5.0),
        Module1.Expr.Num(6.0)),
        Module1.Expr.Div(
            Module1.Expr.Num(5.0),
            Module1.Expr.Num(2.0)));

Console.WriteLine(Module1.Calc(expr));



위 코드를 보시면, 지난주에 계산을 위해서 만들었던 식을 그대로 C#에서 생성했습니다. 실행결과는 아래와 같습니다. 




-정리하며

아~ 간단한 포스트였군요~. 대략 F#에서 만든 코드를 이런식으로 C#등의 다른 언어에서 호출해서 사용할 수 있습니다. 어느덧 베타1이 나온지도 꽤 됀 느낌이네요. 많이들 익숙해지셨나요? VS2008에서 뭔가를 만들다가 C#4.0의 dynamic을 쓰면 딱이겠다고 생각하는 순간, 아쉬움이 느껴지더군요. 아직 F#은 그만큼 익숙하지 못해서 그런경우는 없었던거 같네요-_-;;; 언제쯤 F#의 Jedi가 될 수 있을까요? ㅋㅋㅋ.


-참고자료

1. Expert F#, Don Syme, Adam Granicz,Antonio Cisternino, Apress

Silverlight 3 & Blend 3 RC 공개!!!

RIA 2009. 7. 10. 01:50 Posted by 알 수 없는 사용자


Silverlight 3 정식버전이 드디어 공개됐습니다. 현지 시간으로 7월 10일에 공개된다는 기사가 있었는데 약간 일찍 나왔습니다.
Blend 3도 공개됐는데 RC라고 붙은거 보니 아직 완전 정식판은 아닌 것 같네요.
그래도 이번에는 SketchFlow까지 포함되어서 MIX09에서 보여 주었던 모든 기능을 사용 할 수 있습니다.
Deep Zoom Composer도 역시 Silverlight 3에 맞게 업데이트 되었습니다.

아래 링크에서 다운받을 수 있습니다.
Silverlight 3 Tools 설치하시면 SDK도 같이 설치되니 한번에 설치 하실 분들은 참고하세요.

Welcome to F#(11) - 차별을 권장하는 언어인거임?!?!

F# 2009. 7. 8. 22:51 Posted by 알 수 없는 사용자

- 이말이 사실인게냐

discriminate는 (1)여러가지가 있을때 그것들이 서로 다르다는 걸 인식할 수 있다는 의미 (2) 특정한 단체의 사람들에게 against해서 쓰일때는 그 사람들에게 뭔가 부당하게 불이익이나 이익을 주는 의미를 가지고 있습니다.

즉, 둘다 차이에 근거한 의미인데요 첫째는 구별정도가 되겠고 둘째는 차별정도가 되겠네요. F#은 Discriminated Union(이하 union)이라는 아주 쓸모있는 기능을 가지고 있습니다. 그렇다면 F#은 차별을 권장하는 언어로서 인류발전에 그닥 긍정적이지 못한 언어일까요? 다행히 F#에서의 Discriminated는 첫번째인 구별의 의미로 쓰입니다.(뭐가 다행이지?-_-)


- 영단어엔 관심없는거임. 소스내놓으라해.

union의 형태는 아래와 같습니다. 


  type type-name =
   | case-identifier1 [of type1 [ * type2 ...]
   | case-identifier2 [of type3 [ * type4 ...] 


type키워드에 타입이름이 따라오고요 그리고 등호기호, 그리고 수직파이프(|) 문자로 나눠지는 식별자와 식별자의 타입리스트가 이어집니다. 저기서 각각의 식별자(case-identifier)를 discriminator(이하 구분자)라고 하는군요. 바로 차별구분자인거죠. 사칙연산 계산기를 구현하는 짧막한 코드를 완성해가면서 알아볼까요?


 type Expr =
    | Num of float
    | Add of Expr * Expr
    | Sub of Expr * Expr
    | Mul of Expr * Expr
    | Div of Expr * Expr


위 코드는 간단한 사칙연산에 필요한 구분자를 union을 이용해서 선언한 코드입니다. 다섯개의 구분자를 정의하고 있는데요. Num은 그냥 float타입이고, 나머지는 float * float인 tuple타입입니다. 나머지코드를 보시기전에 이 union만 가지고 이야기 해보도록 하죠. 이걸 어케 쓸까요? 


 

위의 그림을 보시면, 저렇게 쓰는거구나~ 하고 아실 수 있습니다. 구분자의 이름을 주고 괄호안에 구분자의 타입에 해당하는 값을 넣어주면 되는거죠. 그러면 Expr타입의 Num이라는 구분자이고 값은 float타입인 5.0을 가지고 있구나~ 하고 알마먹는 것이죠. Add도 마찬가지로 이해할 수 있습니다. 그리고 위의 union의 정의에 이어서 계산에 쓸 수식을 하나 정의해보죠. 

 let expr = Mul(Add(Num(5.0), Num(6.0)), Div(Num(5.0), Num(2.0))) // (5+6) * (5 /2)


주석에 나와있듯이 (5+6) * (5/2)를 위의 구분자로 표현한 수식입니다. 그러면, union을 이렇게 선언해서 구분자를 저렇에 선언한다는건 알겠는데, 저걸 어따써먹는건지 하는 궁금증이 생깁니다. union과 찰떡궁합인게 바로 pattern matching입니다. 아래의 코드를 보시죠

 let rec Calc expr =
    match expr with
    | Num num -> num
    | Add (e1, e2) -> (Calc e1) + (Calc e2)
    | Sub (e1, e2) -> (Calc e1) - (Calc e2)
    | Mul (e1, e2) -> (Calc e1) * (Calc e2)
    | Div (e1, e2) -> (Calc e1) / (Calc e2)

 
위의 코드는 제귀호출이 가능한 Calc라는 메서드인데요 expr이라는 인자를 하나 받습니다. 그리고 그 expr을 가지고 일치하는 패턴을 찾습니다. 말로 하지 말고 그림으로 하겠습니다! 아래의 그림을 보시져.(잘 안보이심 클릭해서 크게보시길...-_-)
 

 

왼쪽 상단은 F# Interactive에서 입력한 부분이고, 오른쪽 하단은 패턴매칭하는 코드 부분이죠. Num(5.0)의 실제 타입은 "Num 5.0"이고 그게 그대로 "Num num"부분에 매칭이 되면서, num의 값은 5.0이 되는거죠. 패턴매칭의 결과로 (Num 5.0) 은 그냥 5.0을 리턴합니다. 그리고 Add(Num 4.0,Num 9.0)도 각각의 Num이 e1, e2에 매칭이 돼서 Calc를 다시 호출하는 모습입니다. 물론 결과적으로 (Num 4.0) -> 4.0, (Num 9.0) -> 9.0이 리턴되면서 두수의 합이 리턴되겠죠. 그러면 마지막으로 결과를 출력합니다.
 

 Calc expr |> printfn "%f"


위의 코드를 실행한 결과는 아래와 같습니다.
 


제대로 결과가 출력된 게 보이시죠? ㅋㅋㅋ. 그럼 오늘도 지난번 처럼 ildasm을 통해서 IL코드를 둘러볼까 합니다.

 
위 사진을 보시면 지난 포스트의 curry처럼 Expr도 클래스로 선언된걸 확인하실 수 있고, union의 구분자중의 하나인 Num도 Expr내부에 중첩된 클래스로 선언되어 있는걸 보실 수 있습니다. 그리고 Num이 float을 하나 가지는데 그게 num1이라는 이름으로 선언되어있는 걸 IL코드를 통해서도 확인해보실 수 있습니다. 즉, 내부적으로는 구분자별로 클래스를 선언해서 타입으로 검사를 하는걸로 생각할 수 있겠네요. 아래에 보시면 그 타입검사를 위한 메서드들이 선언되어있는걸 확인하실 수 있습니다.
 

 

그리고 마지막으로 MSDN에 나와있는 예제를 하나 보도록 하겠습니다. 

type MilkOption =
   | Nonfat
   | TwoPercent
   | Whole
   | Soy
   | Rice
  
type FlavorOption = string
  
type Brand = string

type Size =
   | Short
   | Tall
  
type TeaFlavor = string
type Shots = int

type CoffeeType =
   | Drip
   | EspressoShot
   | Cappuccino
   | Latte of Size * MilkOption * Shots
   | FlavoredLatte of Size * MilkOption * FlavorOption * Shots

type Drink =
   | Can of Brand
   | Coffee of CoffeeType
   | Tea of TeaFlavor

let drink1 = Can("Coke")
let drink2 = Coffee(Drip)
let drink3 = Coffee(Latte(Tall, Nonfat, 2))
// A single short soy latte with hazelnut
let drink4 = Coffee(FlavoredLatte(Short, Soy, "Hazelnut", 1))

union을 통해서 커피가 캔인지 뽑은 커피인지, 커피이외의 차종류인지부터 시작해서 커피의 종류에서, 사이즈, 샷의횟수등 까지 절묘하게 조합하는 모습을 보실 수 있습니다.

 

- 정리하며

F#은 이렇게 union을 쉽게쓸 수 있는 언어적 특성덕분에 DSL(Domain Specific Language, 다른말로 Language Oriented Progamming이라고도 함)을 잘 지원할 수 있는 능력이 있습니다. 물론 DSL은 그리 쉬운 주제는 아니지만, F#과 함께 천천히 시작해보는 것도 나쁘진 않을 거 같습니다. DSL이나 LOP에 대해서 더 설명을 드릴 수 있으면 좋겠지만, 내공이 허락치 않는군요-_-;;;;;;;;;;


- 참고자료

1.  http://msdn.microsoft.com/en-us/library/dd233226(VS.100).aspx
2.  http://sdasrath.blogspot.com/2009/02/20090220-f-types-discriminated-unions.html
3. Expert F#,  Don Syme, Adam Granicz, Antonio Cisternino, Apress

[ASP.NET 4.0] 2. AJAX - Declarative Client Template Rendering

ASP.NET 4.0 2009. 7. 8. 17:43 Posted by 알 수 없는 사용자
New Feature of Ajax

ATLAS라는 코드명으로 2006년 ASP.NET에 추가된 Ajax가 점점 견고해 지고 있습니다. 2006년 CTP버전 이었던 ATLAS를 겁없이(?) 프로젝트에 적용했었던 기억이 떠오르는 군요. 2006년을 기억하면, 참 MS에서 새로운 기술이 쏟아져 나오던 한해 였습니다. Vista가 공개 되고 WinFX와 WPF, WF(그때는 WWF 로 소개 되었었죠), WCF, ASP.NET에 Ajax 등등 많은 기술이 소개되어 .NET 개발자들의 정신 건강을 악화시켰던 때였습니다.
Ajax는 Google을 선두로 하여 Web 2.0에 적절한 패러다임을 제공하였으며, 국내에서도 많은 파장을 일으켰습니다. 특히, MS에서 나온 Ajax는 개발자의 개발 편의성을 확장시켜 Ajax 대중화에 큰 역활을 하였습니다.

이번 ASP.NET 4.0에 Ajax는 Data Provider의 접근 용이성에 중점을 둔듯 합니다. WCF와 ADO.NET을 이용하여 Client Based Development를 확장시켰으며, DataView는 Client Side에서 개발자가 편하게 화면을 개발 할 수 있도록 리스트 컨트롤을 제공하고 있습니다.

Client Template Rendering - DataView

DataView는 이번에 추가된 기능으로 이전까지는 Server Control을 이용한 리스트를 제공한 반면, Client Side Control을 사용함으로써, Server의 부하를 줄일 수 있도록하는 기능입니다. 예전에는 반복문을 통해 DOM을 생성한다든지, 아니면 개발자 자신의 라이브러리를 활용하거나, Third party 솔루션을 이용하는 방법이 있었습니다만, System.Web.Extention 4.0버전 부터는 기본적으로 DataView라는 컨트롤을 제공해 주고 있습니다. 그리고, 굳이 ASP.NET 언어가 아닌 다른 Framework에서도 사용가능한 독립형 스크립트로 제공하여 주고 있어 플랫폼 대한 제약을 많이 완화 시켰습니다.


간략하게 기능을 알아보도록 하겠습니다.

선언적 구문으로 생성하는 DataView

WebSite 프로젝트를 생성하고 간단한 html문서 또는 aspx 문서를 생성해 보겠습니다. <head>섹션에
<script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjax.debug.js"></script><script type="text/javascript" src="../MicrosoftAjax/MicrosoftAjaxTemplates.debug.js"></script>

AJAX Template을 사용하려면 이 스크립트 참조를 꼭 기입하여야 정상적으로 Template이 생성되는 보실 수 있습니다. 그리고 Body 부분에 해당 Namespace와 Command를 추가해 줍니다.
<body xmlns:sys="javascript:Sys" xmlns:dataview="javascript:Sys.UI.DataView" sys:activate="*">
xmlns:sys="javascript:Sys"는 Sys라는 Namespace를 등록 시켜 줌으로써 선언적(Declarative) 또는 명령적(Imperative)인 모든 Template을 활성화 하는데 필요합니다. 아마도 Ajax를 프로그래밍적으로 접근 하셨던 분들은 Microsoft Ajax Library의 Namespace가 Sys. 이렇게 접두어를 붙여 사용되는 것을 보셨겁니다. 그리고 나머지 두 Attribute는 선언적(Declarative)으로 활성화하거나 바인딩 하는데 필요한 Attribute입니다. dataview또한 네임스페이스로써 Sys.UI.DataView의 AJAX 컨트롤을 의미합니다. 그리고 sys:activate="*"라는 Attribute는 페이지 로드시에 Template을 바인딩하는 특정 개체를 의미하는데 '*'(Asterisk)를 편의상 어떤것이든 활성화 하겠다는 뜻이고 만약 pane1, panel2에 Template을 바인딩 하려면 sys:activate="panel1, panel2"라고 명시적으로 코딩하시면 됩니다.
그리고 실제 Template이 들어갈 개체의 코드를 구현하여 보겠습니다.

<ul id="testDataView" class="sys-template" sys:attach="dataview" dataview:data="{{ testData }}">        <li>            <span class="name">{{ Name }}</span>            <span class="value">{{ Value }}</span>        </li></ul>
ul안에 id와 class 그리고 sys:attach, dataview:data와 같은 예전에 보던 Attribute와 생전 처음 쌩뚱 맞은 Attribute가 ul 태그 안에 들어와 있는 것을 보실 수 있습니다. 일단 "sys-template"이 거슬리는 군요.
sys-template은 일종에 예약된 스타일이라고 이해하시면 됩니다. 만약 Template을 구현 하고 class에 sys-template을 명시적으로 넣어 주시지 않으시면, 효과가 즉빵 나타납니다. 어떤 효과일까요? 리스트가 아예 안나옵니다. 헐~ 필자도 처음에는 내 나름대로의 스타일을 줬다가 몇분 삽질하고, 이런 교훈을 얻었습니다. 아무튼  testStyleSheet.css스타일 시트를 만드셨다면 그 시트 안에는 .sys-template { display:none; } 이라는 스타일이 있어야 합니다. 다시 정리 하자면 sys-template 은 Template에 바인딩이 일어나기 전까지 Template을 숨기는 예약된 스타일이라고 정의하겠습니다. 

그리고, sys:attatch는 또 뭐하는 아이이길래 우리를 헷깔리게 하는 것일까요? 음, 예전에 Microsoft AJAX Library를 프로그래밍적으로 다루어 보셨던 분들이라면 생소 하지 않는 $Create라는 메서드를 기억하실 겁니다. 이놈은 개체를 생성하는 아이인데 Sys.으로 파생되는 개체들을 생성하는 메서드라고 할 수 있습니다. 즉 Microsoft AJAX Library에서만 파생된 개체들을 쉽게 생성하고자 만들어진 메서드입니다. 그럼 sys:attatch와 $Create와는 무슨 관계일까요? 답은 같은 놈입니다. 다만 선언적으로 태그의 Attribute에 위치하느냐, 프로그래밍적으로 접근하느냐하는 방법의 차이일 뿐이지 같은 의미를 지녔습니다. 마지막으로 dataview:data는 body태그에서 Namespace를 정의해 주었던거 생각 나시죠? 그 접두어에 data는~~~~~~~ 네 맞습니다. Data Source입니다. 우리가 리스트를 주욱 바인딩 할 데이터 소스 개체를 정의해 주는 Attribute입니다.
그럼, 이제 어느정도 Attribute에 대한 이해가 되었으리라 생각하고 다음 코딩으로 넘어 가겠습니다.

Add array DataSource

다음과 같이 Array로 DataSource를 생성합니다. 다음에는 ADO.NET과 WCF로 바인딩하는 포스팅을 하도록 하겠습니다.
<script type="text/javascript">        
var testData = [
            { Name: "홍길동", Value: "의적" },
            { Name: "김혜자", Value: "영화배우" },
            { Name: "원빈", Value: "영화배우" },
            { Name: "김태희", Value: "이쁜이" },
            { Name: "전지현", Value: "절세미인" },
            { Name: "2PM", Value: "가수" },
            { Name: "장동건", Value: "영화배우." },
            { Name: "카라", Value: "귀염둥이들" },
            { Name: "이수근", Value: "코메디언" },
            { Name: "강호동", Value: "돼랑이" },
            { Name: "유재석", Value: "메뚜기" },
            { Name: "이효리", Value: "횰" },
            { Name: "정형돈", Value: "정체불명" },
            { Name: "길", Value: "가수" }        ];
</script>

다들 아시겠지만 굳이 부연 설명 드리도록 하겠습니다. javascript는 함수형 언어로써 강력한 기능을 제공합니다. 보시는 바와 같이 단순히 Array 이지만 testData라는 개체에 Name과 Value라는 Attribute가 있는 개체들의 집합이 들어 가게 되는 것입니다. 우리가 생각 하는 new의 연산자와 javascript의 new 연산자는 다른 의미라는 것을 알고 계실 듯 합니다. 여기에서도 유추를 하실 수 있습니다. 혹, testData[0].Name일 경우 홍길동이 나타나는 결과를 얻으실 수 있습니다.
이제 실제 결과 페이지를 보고 이번 포스팅을 마무리 하겠습니다.

지난 6월 10일 VSTS 2010 팀에서 세미나를 진행하였습니다. 세미나 프레젠테이션은 MEF 세미나 자료 에서 볼 수 있습니다.

그리고 얼마 전에 촬영한 동영상도 공개가 되었습니다. VSTS 2010 은 굉장히 큰 규모의 개발 도구, 개발 플랫폼 등의 버전 업으로 아직도 많은 부분을 알려드리지 못했고, 미처 저희들도 모두 알지 못하는 부분도 많습니다.

하지만 남들보다 먼저 접해본 분야이고 이것을 알려드리기 위해 진행한 세미나입니다. 아래의 동영상을 시청하시고 VSTS 2010 에 많은 관심을 가져주세요. ^^

   

강보람 - C# 연대기 - C# 의 Before/After

   

공성의 - VSTS 2010 의 소프트웨어 품질 관리

   

김병진님의 - VSTS 2010 Architecture & UML

   

   

엄준일 ASP.NET MVP - Managed Extensibility Framework

   

최흥배 C++ MVP - Visual C++ 10, C++0x 그리고 Concurrency Runtime

   

VSTS 2010 팀 3분기 맴버 모집

VSTS 2010 팀 블로그 2009. 7. 6. 15:22 Posted by POWERUMC

안녕하세요. 저희 VSTS 2010 팀 블로그는 .NET Framework 4.0 과 VSTS 2010 에 대한 정보를 제공하는 공식 팀 블로그 입니다.

   

현재 저희 팀은 학생을 비롯하여, 개발자, 아키텍처, 컨설턴트 등 다양한 분야의 전문가와 Microsoft MVP 분들이 현재까지도 활동을 하고 계십니다.

VSTS 2010 팀의 지난 2분기 활동을 모두 마치고, 올해 3분기를 이끌어가실 새로운 팀 맴버를 모집합니다. 저희 팀에서는 아래와 같은 활동을 하게 됩니다.

   

VSTS 2010 팀 활동 분야   

스터디

매월 2 오프라인 스터디를 운영하여, 기술적인 부분을 공유하고 토론하는 시간을 갖습니다.

블로그

팀 블로그를 통해 자신만의 분야 또는 배우고 싶은 분야를 공부하여 블로그에 게시할 수 있는 공간을 제공합니다. 다양한 분야의 전문가들도 함께 참여하여 VSTS 2010 에 대한  중요한 피드를 제공합니다.

세미나 기타 활동

세미나 강사 또는 다양한 외부 활동의 기회를 제공해 줍니다.

Microsoft MVP 추천

Microsoft Korea MVP Lead, Microsoft D&PE, Microsoft MVP 추천을 드리며 적극 지원해 드립니다.


모집 대상

대상

무관

지원 자격

1.     .NET Framework 3.5 와 Visual Studio 2008 의 신 기능에 대해 알고 있는 분
2.     자신의 블로그를 운영하고 계신 분
3.     무언가에 도전하고 싶은 열정을 갖은 분

모집 분야

  • Cloud Development
  • Parallel Development
  • Web Development
  • Windows 7 Development
  • RIA Development
  • Architect Development
  • Office Business Application Development
  • .NET Framework 4.0
  • Visual Studio 2010
  • Visual Studio Team System 2010
  • ETC…

   

   

지원 방법

아래의 자신의 프로필을 umc골뱅이dotnetxpert.com 으로 보내주십시오. 반드시 아래의 양식을 지켜주십시오.

이름

홍길동

블로그

자신의 블로그 주소

소개

회사 및 소속, 자신의 소개

지원 분야

Web Development (중복 가능)

   

마감

2009년 7월 16일까지 지원 메일을 받습니다. 많은 지원 바랍니다. ^^

   

참고로 배우고자 지원하시는 분들은 정중히 사과드립니다. 저희 팀의 스터디에서는 여러분들에게 아무것도 가르쳐주지 않습니다.

저희 팀에서는 실력을 보고 맴버를 선발하지 않습니다. 물론 실력이 출중하면 좋겠지만 새로운 VSTS 2010 분야는 어느 누구도 밟아보지 않은 새로운 황야와 같습니다. 새로운 길을 함께 가실 활동력이 충분하신 분들은 꼭 지원해 주시기 바랍니다. ^^

일곱,여덟번째로 드디어 마지막입니다. ㅠㅠ

역시나 Q&A가 이어지고, 끝에 선물을 주네요.


그 동안 시청해주셔서 감사합니다. 조만간 새로운 내용으로 다시 돌아오겠습니다. ^^

p.s. 필요하다는 분이 계서서 이제까지의 자막 파일들 첨부합니다.


Welcome to F#(10) - 인도음식 카레.....?

F# 2009. 7. 3. 13:39 Posted by 알 수 없는 사용자

- 카레랑 F#이랑 뭔 상관이야.

우리나라말로 카레. 영어로 curry인거죠. F#에선(함수형 언어에선) 카레를 맛보실 수 있습니다. 음미하고 먹으려면 좀 복잡한 과정을 거쳐야 할지도 모르지만요. 그래서 기꺼이 드셔보시고자 하시는 분들. 어떻게 먹는지 천천히 이야기 해보시죠 캬캬캬캬캬...


- 모야 먹는거 아니자나+_+

Curry는 수학과 컴퓨터과학에서 사용되는 특정한 기술을 가리키는 말로서, 미국의 수리논리학자였던 Haskell Brooks Curry의 이름을 따서 지어졌다고 합니다. Haskell이라는 언어도 Haskell Brooks Curry의 이름을 따서 만들어졌죠. Curry는 함수형 프로그래밍의 기초를 쌓았던 사람중의 한명이라고 합니다. 아마도 그래서 함수형언어중에 그의 이름을 딴 언어와 기능이 있는것 같습니다.

Curry의 사후에 새로만들 언어의 이름을 Haskell로 하기로 정하고 그의 미망인에게 가서 언어의 이름을 Haskell로 정해도 좋겠냐고 하자 흔쾌히 허락하면서도 그가 한번도 Haskell이라는 이름을 좋아한 적이 없었다고 말했다는 군요. 본인이 좋아했든 안했든 Haskell과 Curry라는 이름은 프로그래밍언어의 역사속에서 영원히 기억되겠죠. 아... 행복한 사람이구만 ㅋㅋㅋ. 완전 부럽네. -_- 

어쨌든 currying은 "다수개의 인자를 받는 함수를 하나의 인자를 받는 함수로 만들고 나머지 인자를 받는 함수를 리턴하는 변환의 절차"라고 합니다. 무슨 말인지 이해가 가시나요? 음-_-;; 간단히 알아보도록 하죠. 


위의 그림을 보시면, 우선 add라는 인자 두개를 받아서 더한 결과를 리턴하는 함수를 선언한 걸 보실 수 있습니다. 즉, "add 3 5" 같은 형태로 사용하는거 겠죠. 하지만, currying을 하게되면, 다수개의 인자(a, b 두개)를 받는 함수(add)를 하나의 인자(a)를 받는 함수로 만들고 나머지 인자(b)를 받는 함수를 리턴하게 할 수 있습니다. 다음 그림이 바로 그 내용이죠. 


보시면 add5는 add 5의 결과, 즉 "add a b"에서 a에 5를 넣은 "add 5 b"를 가리키게 됩니다. 즉, 커리의 정의에 따르면, add5는 여러개의 인자를 받는 함수(add)를 하나의 인자를 받는 함수로 변환해서(add 5) 나머지 인자를 받는 함수를 리턴합니다.

위 사진에서 add5의 타입을 보시면, (int -> int), int하나를 받아서 int를 리턴하는 함수임을 보여주고 있습니다. 하지만 add5는 받는 인자가 없습니다. 즉, "add 5 b"에서 인자 하나를 제외한 나머지 b를 add5가 인자로 받아서 5 + b의 결과를 리턴하는 함수라는 말이죠. 


그리고 result에 "add5 10"의 결과를 대입합니다. 그 결과는 add함수의 나머지 하나의 파라미터에 10을 집어넣은 즉, 5 + 10의 결과값인 15가 들어가겠죠.

 

 

위 그림에서 그 결과를 확인하실 수 있습니다. 위의 단계들을 그림으로 설명해보면 아래와 같습니다.

 

 

그리고 실제로 생성되는 IL코드를 통해서도 한번 확인해보도록 하겠습니다.

 

 

빌드한 코드를 ildasm을 통해서 보고있는건데요. 신기한건, add5가 클래스의 형태로 되어있다는 겁니다. ".ctor"은 생성자를 의미하죠. 그리고 멤버변수로 a가 들어가 있습니다. "add5 = add 5"가 클래스의 형태로 만들어지고 5는 멤버변수로 저장되어 있다가 나중에 호출될때 사용되는거 같군요. 그러면 add5의 호출부분인 Invoke쪽을 보겠습니다.

 

 

빨간박스로 표시된 부분을 위에서 부터 차례대로 보시면 add5는 "b"라는 int32형 인자를 하나 받아서 호출됩니다. 그리고 멤버변수인 a를 로드하구요, 그 둘을 가지고 add메서드를 호출합니다. 그렇습니다. 내부적으로는 이렇게 처리를 하는군요.

제가 왜 이렇게 curry에 대해서 설명을 드리는고 하니, 바로 F#의 기반에 그 curry가 깔려있기 때문이죠. 아래의 그림에서 뭔가 이상한걸 느끼셨다면, 바로 그게 curry입니다.

 

 

즉, "->'이게 들어가있으면 함수라는 이야기 인데, "add a = a + 5"같은 함수라면, 아... 이게 정수를 하나받아서 거기에 5를 더한 정수를 하나 리턴하는 구나.... 해서 "int -> int"라는게 이해가 되는데, 어째서 "add a b = a + b"는 "int -> int -> int"일까요? 그렇습니다. 내부적으로 curry를 사용하고 있기 때문입니다.

즉, "add 3 5"라고 해주더라도 curry를 통해서 "add 3 "을 통해서 3을 인자로 받고 정수형 인자 하나를 받는 함수를 리턴합니다. 그리고 그 함수에 5를 넘겨줘서 결과값인 8을 얻게 됩니다. 그래서 int를 받아서 "int -> int"인 함수를 리턴하고, 그 "int -> int"인 함수에 다시 int를 하나 넘겨줘서 결과로 int를 받는거죠. 이번에도 그림으로 정리해보면 아래와 같습니다.(별 도움이 안되는거 같지만 정성을 생각해서 자비좀....-_- ㅋㅋㅋ)

 

 

- 정리하며

넵, 오늘은 curry에 대해서 알아봤습니다. 충분히 설명을 못드린거 같아서 좀 불편한 마음이 있군요. 모든건 제 책임이니 저에게 따스한 격려를(?)....... 암튼, 이렇게 curry를 이용하게 되면, 위에서 보셨듯이 하나의 함수에서 새로운 함수들을 계속 해서 만들어 낼 수 있고, 그렇게 함수를 프로그램을 만들어가는 building block으로 사용할 수 있습니다. 더 구체적인 예를 드리지 못해서 아쉽군요. 더 공부해서 내공이 허락한다면 더 설명드리도록 하겠습니다.

 

- 참고자료

1. http://geekswithblogs.net/Podwysocki/archive/2008/02/21/119880.aspx
2. http://diditwith.net/2007/08/15/TheArtOfCurrying.aspx
3. http://www.dotnetrocks.com/default.aspx?showNum=310

[VSIX] 2-2. How to start VSIX programming

VIsual Studio Extensibility 2009. 6. 29. 18:47 Posted by 알 수 없는 사용자
Setting up the infrastructure for developing VSIX

개발을 시작하기 전 기본적인 인프라 구성을 먼저 하여 봅니다. 일단 Visual Studio 2010 을 다운로드 받아 설치해 보도록 하겠습니다.


친절하게도 이전에 슈러님께서 포스팅한 글이 있으므로 참고하면서 설치 하도록 하고, 이제 Visual Studio 2010 Beta 1 SDK를 설치 해 보도록 하겠습니다.

Installing Visual Studio 2010 SDK Beta 1


참고 링크를 따라 이동 하면 그림 1-1과 같은 Microsoft Download Center의 웹페이지가 나타날 것입니다. 거기서 Download 버튼 클릭 하면 Visual Studio 2010 SDK Beta 1을 다운로드 하실 수 있습니다. Release 날짜가 2009년 6월 12일로 다소 따끈 따끈한(?) 아이입니다.
Visual Studio 2010 SDK에는 Tool Windows, Menu Commands, Isolated Shell Projects, Editor Extension을 생성 할 수 있도록 프로젝트 템플릿을 제공하고 있으며, Editor Extension에는 Text Adorment, Colorizer, Magin 템플릿을 포함하고 있고, 빌드와 디버그 Extension은 개발자에게 VSX를 개발
                                                                           <그림 1-1>      하는데 큰 도움을 줍니다.

                                                                                                                         <그림 1-2>
그림 1-2는 초기 Visual Studio 2010 SDK Beta 1 Setup 화면입니다 Next버튼을 클릭하여 다음으로 넘어 갑니다. 그림 1-3과 같이 라이센스 동의 화면이 나타나는데 역시나 인스톨할 때 화면들이기 때문에 다음버튼만 죽어라 누르면 됩니다. 

                                                                                                                         <그림 1-3>
그리고 설치 경로를 물어보고 다음 버튼을 선택하면 설치를 시작합니다. 설치 시간은 대략 몇분이면 마무리 되므로 큰 인내심은 필요치 않습니다. 그리고 정확히 DSL 부분까지 파고 들어갈지 의문이기 때문에 만약 DSL도 다루게 된다면 그때가서 설치 부분을 포스팅 할지를 생각해 보도록 하겠습니다.

VSX를 개발하기 위한 물밑 작업은 완료 되었습니다. 참 쉽~죠잉~!
File > New > Project 를 클릭하면 그림 1-4와 같이 Extensibility 메뉴에 해당 Project Templete이 생성되어 있는 것을 확인 하실 수 있습니다.
                                                                                                                                    <그림 1-4>

다음 포스팅에서는 Editor Templete에 기능에 대하여 알아 보도록 하겠습니다.

[Testing] Moq.NET (T/B Driven Development)

Agile Development 2009. 6. 29. 12:36 Posted by POWERUMC

 

Moq.NET

Moq 는 "Mock-you" 또는 "Mock" 로 부른다고 합니다. Moq.NET 3.0 은 C# 3.0 과 .NET Framework 3.5 를 통해 Linq Expression Tree 와 Lambda Expression(람대 표현식) 으로 직관적이고 생산적이라고 합니다.

이전에 봤던 웹 사이트 로그인 사용자 스토리를 다시 봅시다. 단, 이 예제에서는 복잡성을 만족하는 항목을 삭제합니다.

웹 사이트의 로그인 사용자 스토리

  • 사용자 아이디는 영문만 입력 가능하고 한글은 입력할 수 없다
  • 사용자 아이디는 최소 3자리, 최대 10자리까지 입력가능하고 초과시 경고 메시지를 보여준다
  • 사용자 비밀번호는 최소 5자리, 최대 20자리까지 입력 가능하고 초과시 경고 메시지를 보여준다

   

위의 사용자 스토리를 Mocking Framework 인 Moq.NET 을 이용하여 TDD와 BDD 형태로 테스트를 작성해 나갈 수 있습니다.

아래의 소스 코드는 Login 인터페이스를 정의한 코드입니다.

public interface ILogin
{

LoginResult Login(string id, string password);

LoginInputResult Valide(string id, string password);

}

   

public enum LoginResult

{

Authentication,

NoAuthentication

}

   

public enum LoginInputResult

{

Success,

MinLengthId,

MaxLengthId,

MinLengthPassword,

MaxLengthPassword

}

   

이제 Login 의 Behavior(행위) 측면에서 주도적인 개발을 하고자 합니다. BDD 이용하여 [그림1] 의 Clean up code 를 얻기 위한 목적이 아닙니다. 좀 더 TDD 에 가깝고, 디자인과 설계에 초점을 맞추고자 합니다.

class Program
{

static void Main(string[] args)

{

var id = "powerumc";

var pwd = "aaaa";

var mock = new Mock<ILogin>();

}

   

private static string minString(int length)

{

return Match<string>.Create( o => o.Length <= length );

}

   

private static string maxString(int length)

{

return Match<string>.Create( o => o.Length >= length );

}

}

   

위의 코드를 통해 Mocking Object 를 생성하도록 Mock<T> 생성자를 볼 수 있습니다. 바로 Mock<T> 를 통해 Mocking Object 를 생성합니다.

아래의 코드는 위의 로그인 사용자 스토리에서 입력되는 아이디/비밀번호의 유효성을 검사하도록 Mocking Object 를 설정합니다.

// Validate

mock.Setup( o => o.Valide(minString(3), It.IsAny<string>()))

.Returns(LoginInputResult.MinLengthId)

.Callback(()=>Console.WriteLine("ERROR> MinLengthId"));

mock.Setup( o => o.Valide(maxString(10), It.IsAny<string>()))

.Returns(LoginInputResult.MaxLengthId)

.Callback(()=>Console.WriteLine("ERROR> MaxLengthId"));

mock.Setup( o => o.Valide(It.IsAny<string>(), minString(3)))

.Returns(LoginInputResult.MinLengthPassword)

.Callback(()=>Console.WriteLine("ERROR> MinLengthPassword"));

mock.Setup( o => o.Valide(It.IsAny<string>(), maxString(20)))

.Returns(LoginInputResult.MaxLengthPassword)

.Callback(()=>Console.WriteLine("ERROR> MaxLengthPassword"));

   

아래의 코드는 유효성을 통과한 아이디/비밀번호로 로그인을 시도하고 결과값을 리턴하는 Mocking Object 입니다.

// Login

mock.Setup( o => o.Login(It.IsAny<string>(), It.IsAny<string>()))

.Returns(LoginResult.NoAuthentication)

.Callback(()=>Console.WriteLine("No Authentication"));

mock.Setup( o => o.Login(id, pwd))

.Returns(LoginResult.Authentication)

.Callback(()=>Console.WriteLine("Success Login"));

   

자, 그럼 가상의 Mocking Object 를 통해 인터페이스만으로 로그인 시도를 해보도록 하겠습니다.

var obj = mock.Object;

var loginInputResult = obj.Valide(id,pwd);

   

if( loginInputResult != LoginInputResult.Success ) return;

   

obj.Login(id,pwd);

   

입력 변수 값에 따라 비록 Mocking Object 지만, 테스트 시나리오를 충분히 검증할 수 있습니다.

Id="aaa", pwd="aaa" 일 경우는 아래와 같은 결과가 나타나겠죠~?

 

Id="powerumc", pwd="aaaa" 일 경우는 아래와 같이 모든 테스트 시나리오를 통과한 결과입니다.

 

그럼, Microsoft Research 프로젝트의 일환인 Pex 를 이용하여 Mocking Object 를 Testing 해보겠습니다. Pex 테스트 프로젝트를 생성하고 아래의 PexMethod 를 만들었습니다.

아래는 테스트 결과입니다. 총 31개의 테스트 케이스 중에 통과되는 1개의 테스트를 확인할 수 있습니다.

자 어떻습니다~? 전혀 구현 코드를 구현하지 않았음에도 인터페이스를 통해 TDD-테스트 주도 개발이 가능합니다. BDD-행위 주도 개발을 통해 번거로운 TDD 의 Red, Green, Refector 의 유한반복 사이클 없이도, 실제 인터페이스의 디자인과 설계에 초점을 맞추어 테스트를 진행하였습니다.

단순히 BDD 가 최고야~ 라는 말은 아닙니다. 우리가 BDD 를 통해 TDD 를 좀 더 쉽고, 근접하게 접근할 수 있습니다. 그리고 코드의 구현이 전혀 없이 오직 디자인과 설계에 초점이 맞추어져 있다는 사실을 알면 됩니다. 바로 Moq.NET 은 Mocking Object 를 통해 TDD 와 BDD 개발을 통해 좀 더 품질 좋은 WhiteBox Testing 의 기대효과를 누릴 수 있습니다.

데이터베이스의 데이터를 조회하여 테스트한다고 할 때에도, 반드시 데이터베이스가 존재하지 않아도 됩니다. 가상의 데이터베이스 커넥션 객체를 만들어서 쓰면 됩니다. 쇼핑몰 사이트에서 결재 프로세스를 테스트해야 하나요? 그렇다면 가상의 객체를 통해 설계된 결재 프로세스가 합당한지 Mocking Object 를 통해 테스트를 하면 됩니다. 그 이후에는 잘 설계된 인터페이스를 구현하기만 하면 되겠죠?

   

이 외에도 WikiPedia 에 Mock Library 의 종류가 있네요. 아무튼 테스트와 Moq.NET 에 대한 내용은 여기까지 하는 것으로 마치도록 하렵니다.

 

참고 문헌

http://en.wikipedia.org/wiki/Mock-object
http://behaviour-driven.org/

그렇다면 BDD (Behavior-Driven Development) !

TDD 는 그렇다고 치고, 이제는 BDD(Behavior-Driven Development-행위 주도 개발) 가 왠말이냐 -_-; 저 또한 Moq 에 생소한 나머지 여기까지 추적하게 되었습니다. 모두가 TDD 가 좋은 줄은 압니다. 종속적인 기능이나 코드가 정상적임을 증명하고 점진적으로 테스트 코드를 만듦으로써 자연스럽게 세부 설계를 생각하게 할 수 있습니다.

나에게 "TDD" 를 요구한다면 나에게 "시간"을 달라

어째든, BDD 는 소프트웨어 품질을 향상하기 위해 개발자간에 협력할 수 있는 Agile Software Development 기법입니다. BDD 의 목표는 TDD 를 수행하기 위한 것이며 TDD 의 접근법을 전환한 것입니다. TDD 의 딱딱한 어휘를 정리하고 설계나 디자인에 초점이 맞추어진 패러다임의 전환이라고 합니다. 그리하여 TDD 를 수행한다는 본질은 변하지 않지만, TDD 를 수행하기 위해 BDD 를 통해 행위 자체는 변할 수 있다는 것입니다.

더 자세한 내용은 아래의 Behavior-Driven Development 공식 사이트를 참고하십시오.

Behaviour-Driven Development
http://behaviour-driven.org/

또한 Agile Software Development 에서 각 이터레이션(Iteration)에서 수행하게 될 사용자 스토리를 통해 기능이나 구현에 대한 스팩을 정의할 수 있습니다. 즉, 애자일의 사용자 스토리는 바로 테스트를 수행하는 테스트 시나리오로 이어지게 됩니다. 헌데, TDD 로만 수행되는 테스트 시나리오는 실제로 변화에 능동적으로 대처하지 못할 수 있는 경우도 존재합니다.

예를 들어, 설계자는 개발자에게 아래의 스팩이 만족하는 로그인 기능의 "사용자 스토리" 를 정의합니다.

웹 사이트의 로그인 사용자 스토리

  • 사용자 아이디는 영문만 입력 가능하고 한글은 입력할 수 없다
  • 사용자 아이디는 최소 3자리, 최대 10자리까지 입력가능하고 초과시 경고 메시지를 보여준다
  • 사용자 비밀번호는 최소 5자리, 최대 20자리까지 입력 가능하고 초과시 경고 메시지를 보여준다
  • 사용자 비밀번호는 복잡성 만족도를 우측에 색깔과 메시지로 보여준다

위의 사용자 스토리에 만족하도록 TDD 를 수행해야 하는데, TDD 를 수행하기 위해서는 반드시 스토리의 우선 순위대로 진행해야 다음의 테스트 코드를 작성할 수 있습니다. 그런데 여기에 엄청난 함정이 있을 수 도 있습니다.

  • 초/중반의 우선순위의 사용자 스토리의 규모가 한 이터레이션의 주기와 맞먹는 경우라면 TDD 를 어떻게 수행할건가요?
  • 또는, 로그인 시나리오(에피소드, 테마) 안에 고객의 쉽지 않은 요구사항이 추가되었다면 어떻게 할건가요?

예를 들면, 설계가 진행 도중 아래와 같은 요구 사항이 추가가 되었다고 가정해 봅시다.

  • 로그인은 SSO(Single Sign On) 을 통해 로그인하며, SSO 중앙 서버를 통해 인증해야 합니다.

 

기가 막히군요. 아직 SSO 서버는 구축이 되지 않은 상태이고, 단일 시스템간에 명확한 프로토콜도 정의되지 않은 시점입니다. TDD 를 수행하기 위해 SSO 중앙 서버와 프로포콜이 구축되지 않는다면 더 이상 로그인과 관련된 작업은 진행할 수 없게 됩니다.

자! 바로 이런 경우 행위 주도 개발-BDD 가 빛을 발할 때입니다. BDD 의 행위 주도 개발은 인터페이스와 구현을 분리하고 인터페이스에 집중할 수 있습니다. 즉, 어떠한 구현 코드가 없이도 BDD 를 통해 인터페이스만으로 테스트나 코드를 통해 설계 작업을 진행할 수 있게 되는 것입니다.

구현 코드가 없이 인터페이스만으로 테스트를 진행한다니요? 이거 말장난 아닙니까? 아닙니다. 객체의 구현은 전혀 알 필요 없습니다. 단, 내부적인 테스트 시나리오를 알고 있는 것만으로 테스트를 진행하게 됨으로써, 인터페이스의 디자인이나 설계에 집중하게 됩니다.