Framework Design Guidelines
The great proof of madness is the disproportion of one’s designs to one’s means.
— Napoleon Bonaparte (1769-1821)
The great proof of madness is the disproportion of one’s designs to one’s means.
— Napoleon Bonaparte (1769-1821)
자바 성능을 결정짓는 코딩 습관과 튜닝 이야기, 이상민 지음, 한빛 미디어
어떤 것에 대한 지식을 효율적으로 습득하는 방법에는, 그 지식에 관해, 체계적으로 분류하고 정리해 놓은 권위 있는 책을 읽는 방법도 있지만, 잡지와 같이 지식들을 그저 늘어놓은 형태의 정보를 접하는 방법도 있다.
이 책은 후자에 해당하는 책이다. 자바의 코딩 습관에 관한 책이나 자바 성능 튜닝에 관한 문서는 있지만, 경험이 부족한 사람들에게 필요한 것은 정보 자체가 아니라 정보에 대한 좋은 레퍼런스가 필요한 경우가 있다.
잡지의 형식의 특성 중 하나는 필자의 경험에 따른, 시간이나 상황, 독자에 맞는 정보들을 보여 주려고 시도한다는 것이다. 권위가 있는 서적에서는 특성상 시간이나 경험에 따라 변할 수 있는 정보를 보여 주려고 하지는 않는다. 그럼에도 불구하고 현실에 살고 있는 우리들은 시간에 따라 변할 수 있는 정보를 필요로 한다. 예를 들어, 최소한 필자 또는 삼성 SDS에서 자주 쓰는 프로파일링 도구는 무엇인가와 같은 정보가 그러한 정보에 해당하는 것이다. (어떤 성능 튜닝 책에서는 프로파일링 도구를 모두 정리해 놓을 수 있지만, 이 책은 그런 것을 시도한 것 같지는 않다.)
이 책의 다른 미덕 하나는 ‘이야기’와 ‘실제 사례’를 들려주려고 시도했다는 점이다. 필요한 정보만 정리되어 담겨 져 있는 책이나 문서가 아니라, 나 같은 경우에도 ‘이야기’가 담겨 있는 책은 훨씬 접하기가 편안하다. 말하자면, 주말에 편한 의자에 앉아서 시간 때우기 용으로 읽거나 심지어는 화장실에서 읽을 수도 있다는 것이다.
최소한 이 책은 초보자를 위한 자바의 기본적인 코딩 습관, 성능 튜닝에 관한 지식 등으로의 참고 자료 또는 잡지가 되는 것에는 성공했다고 생각한다. 다만, 숙련자가 읽기에는 정보의 깊이라든가 정확성 등은 약간 부족한 면이 있다.
몇몇 가벼운 기술 서적들을 읽다가, 다시 IIR을 들어 Chapter 19-21을 읽었습니다.
이제 Chapter 13-18을 읽을 차례군요.
내가 싫어하는 코딩 스타일 중의 하나가 바로 다음과 같은 코딩 스타일이다.
if (BAR == foo) { // whatever.. }
Java에서는 다음과 같이 쓰기도 한다.
if (BAR.equals(foo)) { // whatever.. }
원래 이러한 코딩 스타일은 if 문 내에서 의도하지 않은 assignment가 일어나는 것을 방지하기 위한 것이다.
// XXX: assignment not intended if (foo = BAR) { // whatever.. }
Java의 경우에는 NullPointerException (이하 NPE)을 방지하기 위한 목적도 있다고 한다.
// XXX: when foo is null, throws NPE if (foo.equals(BAR)) { // whatever.. }
일단, 이런 스타일을 싫어하는 첫 번째 이유는 읽기가 힘들다는 것이다. ‘if foo is BAR’는 내 마음의 회로에서 바로 처리가 되지만, ‘if BAR is foo’는 위화감이 있다. 아마도 언어적인 이유이거나 (an student is not me?) 수학식을 읽는 방식 (when pi is x?) 을 기대하기 때문이라고 생각한다.
두 번째 이유는 이러한 스타일을 사용함으로써 얻으려는 이익은 다른 방법으로도 얻을 수 있기 때문이다. 단순히 잘못된 방식이라는 것이다.
일단 conditional에서의 의도하지 않은 assignments를 방지하기 위해서는 이미 오래 전부터 컴파일러가 보여 주고 있는 경고 (warning) 메시지를 이용하면 된다. 게다가 프로그래밍에 익숙해 지면 저런 실수는 흔치는 않은 일이 된다.
NPE의 방지는 방어적인 프로그래밍의 입장에서 일견 설득력이 있어 보이지만, Java의 스타일을 해치고, 결과적으로 오류 가능성을 감추어서 견고한 코드로 만드는 길을 막는다고 생각한다.
일반적인 프로그래밍에서 nullity는 말 그대로 invalidity를 의미하고, Java에서는 이러한 의미를 잘 살려서 코딩 할 수 있다.
Case 1
Foo foo1 = new Foo(); assert foo1 != null; foo1.bar(); Foo foo2 = getValidFoo(); assert foo2 != null; foo2.bar();
foo1과 foo2의 경우가 바로 그런 경우다.
foo1의 경우 Java의 new 키워드를 통해 valid하다는 것 즉, null이 아니라는 것이 보장된다.
getValidFoo()는 항상 valid한 Foo instance를 돌려준다라는 의미를 가지고 있다. 만약 getFooValid()가 null을 돌려준다면 assertion failure나 NPE가 발생할 것이다. 하지만, 그것은 getValidFoo()의 오류이므로, getValidFoo()를 사용하는 코드에서는 이 점을 무시할 수 있다. 그리고, getValidFoo()에서 제대로 Foo instance를 돌려줄 수 없는 상황이라면 exception을 throw할 것이다.
우리는 모든 코드에서 모든 변수의 validity를 체크할 수 있지만, 우리는 단순히 그렇게 하지 않는다. 만약 그렇게 한다면, 그것은 편집증 환자의 코드로 보일 뿐이다. 좋은 프로그래밍 언어는 그렇게 하지 않아도 되도록 하는 여러 장치들(new keyword, types, exception, assertion, …)을 가지고 있다.
만약 getValidFoo()가 믿을 만 하지 않아서 불안하다면 assertion을 사용해 명시적으로 오류를 발생시키면 된다.
Case 2
Foo foo3 = getFoo(); if (foo3 == null) throw new RuntimeException("foo2 is null"); assert foo3 != null; foo3.bar();
getFoo()가 semantic 상으로 null을 돌려줄 수 있을 경우가 있다. 이 경우 우리는 foo의 메서드를 호출할 예정이고 이후로도 다른 처리를 해야 하므로, 명시적으로 nullity 체크를 해서 적절한 처리를 하면 된다.
nullity는 위에서 얘기 한대로 invalidity를 의미하므로 이러한 상황에 대해서는 어떻게 대처할지 미리 준비가 되어 있어야 한다. 단순히 if (foo.equals(BAR))로 해결되었다고 착각하는 것은 위험하다. 그러한 코드가 invalidity 상황을 해결할 수 없다는 것이 아니다. 이러한 코딩 스타일이라는 것은 곧 invalidity 상황에 대해서 무시하는 습관을 들이는 것이랑 같다는 것이다.
한편, Case 1의 getValidFoo() 처럼, 원래의 의미는 validity를 보장해야 하나 실제로 그렇지 않을 경우, 안정성을 보장해야 하는 상황에서, 치명적인 결과를 가져오는 것이 걱정된다면, Case 2로 처리하라. 명시적으로 invalidity 상황을 처리하지 않고 위와 같은 코딩 스타일로 해결하고자 하는 것은 단순히 게으른 것이다.
Case 3
Foo foo4 = getFoo(); if (foo4 == null || foo4.equals(BAR) != true) { // do A } else { // do B } Foo foo5 = getFoo(); if (BAR.equals(foo5)) { // do B } else { // do A } // XXX: possible to throw NPE foo5.bar();
마지막으로, foo4의 nullity가 invalidity라고 보기 힘든 경우가 있다. value object일 경우가 많을 텐데, 이 경우 null인 경우는 foo4의 상태 중 하나일 뿐인 것이다. 이 경우만이 겨우 위의 코딩 스타일이 약간이나마 빛을 발하는 경우라고 볼 수 있는데, 약간의 코드를 절약할 뿐, 충분히 명시적이지 못한 코드라고 생각한다. 만약 단순히 equality test만 있는 것이 아니라 메서드 호출도 필요한 상황이라면 실수할 여지가 있다.
이러한 경우라면 Null Object 패턴을 활용해 보라고 조언하고 싶다.
Foo foo6 = getValidFoo(); assert foo6 != null; if (foo6.equals(BAR)) { // do B } else { // do A } foo6.bar();
즉, null 값으로 invalidity를 표현하지 말고 이를 표현하기 위한 객체를 만드는데, 이렇게 되면, null 값이 다시 invalidity를 의미하게 되므로, Case 1 또는 Case 2와 같은 방식으로 처리하면 된다. 그리고, 훨씬 Java 언어에 자연스러운 스타일이 될 것이다.
Closing
프로그래밍에 있어서 nullity 문제와 같이 사소한 코딩 상의 버그를 발생시키지 않는 비결은 의도를 발생할 수 있는 모든 경우를 명시적으로 처리하는 것이다. 코너 케이스들을 대충 해 놓는 경우들이 자주 보이는데 , 결국은 자신 또는 누군가가 그에 대한 비용을 치르게 될 것이란 점을 기억하라고 조언하고 싶다.
MyISAM을 쓰던 시절에는 당연히 COUNT(val) 보다는 COUNT(*)을 써야 한다는 조언을 들어왔는데, InnoDB에서도 그렇게 해야 하는가는 약간 혼란스러운 문제였다.
Peter Zaitsev의 결론은 대부분의 경우, COUNT(*)를 사용하는 것이 좋다라는 것이지만, 역시 의도에 따라 정확하게 사용하는 것이 가장 바람직하다.
MySQL 5.0 Reference Manual에 따르면, COUNT()의 정확한 의미는 다음과 같다.
MyISAM은 테이블마다 row 개수에 대한 카운터를 가지고 있고, 이 카운터의 이점을 얻으려면 COUNT(*)를 사용하라는 조언이 자주 제시되었는데, COUNT()의 정확한 의미를 알고 나면 이러한 조언의 근거를 알 수 있다.
즉, COUNT(*)는 단순히 row들의 개수를 의미하기 때문에, row 개수에 대한 카운터를 사용할 수 있지만, COUNT(expr)은 non-NULL 값의 개수를 의미하기 때문에, 만약 expr이 NOT NULL constraint를 가진 필드가 아니라면, row 개수에 대한 카운터를 사용할 수가 없다. (물론, NOT NULL constraint를 가진 필드라면 그렇지 않다.)
MyISAM의 row 개수 카운터는 매우 유용하지만, 매우 한정된 쿼리, 즉 전체 row들의 개수를 얻는 데에만 사용할 수 있을 뿐이다.
Update: 오늘 낮에 InnoDB의 구조에 따른 COUNT() 성능에 관해 남세동 팀장님과 이야기를 나누었는데, 집에 돌아와서 실험을 해보니 InnoDB에서는 COUNT()의 쿼리 플랜이 MyISAM의 경우와 확실하게 다른 것으로 보인다. 실험 결과는, 한마디로 하자면, Index가 존재하는 경우에는 Index를 활용하는 쪽으로 플랜이 만들어 지는 것 같다. 정확한 결과는 다음 포스팅에…
Ship It by Jared Richardson, William Gwaltney
Ship It은 소프트웨어 개발에 관한 가이드라인을 담은 책이다. ‘도구와 인프라스트럭처’, ‘실용주의적 프로젝트 기술’, ‘예광탄 개발’, ‘일반적인 문제와 해결방법’의 네 부분으로 나뉜다.
‘도구와 인프라스트럭처’는 CVS 또는 Subversion과 같은 코드 저장소, 빌드의 자동화, 이슈 및 기능 추적, 테스트 자동화와 같은 이슈를 다루고 있다. 사실 이러한 도구들을 사용하라는 가이드라인은 흔히 들을 수 있는 이야기지만, 이 장의 마지막 가이드라인인 ‘실험하지 말아야 할 때’에서는 ‘핵심적인 기술을 기술 실험 대상으로 삼아선 안 됩니다’라는 중요한 교훈을 얘기하고 있다. 의욕에 찬 하지만, 경험은 부족한 개발자들이 흔히 하는 실수다.
‘실용주의적 프로젝트 기술’에서 소개하는 목록 사용은 오래 전부터 나나 내가 일하던 팀, 내 주변의 사람들이 실제로 활용하면서 훌륭한 습관임이 증명된 프랙티스다.
일일 회의나 모든 코드의 검토, 코드 변경 통지 등은 내겐 약간 적용하기 힘들어보이는 프랙티스들인데, 각각의 프랙티스는 나름의 장점들을 갖고 있다는 것에 동의하기 때문에 조금씩 적용해 볼 생각이다.
내가 맡고 있는 조직에 주간 회의를 적용하기 시작한지가 수개월 지났고, 현재는 어느 정도 정착이 되어가고 있다. 하지만, 어차피 작업이나 문제 관리를 위한 의사 소통이 매일 일어나는 것을 생각하면, 일일 회의는 의사소통이 예측 가능하게 일어나게 해주고, 때문에 효율적인 의사소통이 가능하게 해주리라 생각한다. (이는 주간 회의를 포함한 ‘정기적인 회의’의 장점일 것이다.) 하지만, 일일 회의를 시행하기 위해서는 주간 회의라는 익숙한 프랙티스를 포기해야 한다. 이와 같이, 어떤 프랙티스가 좋고, 현재의 프랙티스를 대체하자는 얘기는 너무나 쉽지만, 이것을 적용하기 위한 사람들의 지지를 얻고, 대체 과정의 비용을 줄이고, 실제로 잘 적용하는 것은 여러 고민과 많은 노력이 필요한 일이다.
코드 검토의 경우, 이 책에서는 변경을 포함한 모든 코드를 검토해야 한다고 나와있지만, 그보다 온화한 (덜 진보적인) 단계로, 새로운 모듈이나 프로그램, 시스템이 완성되었을 때, 코드 검토를 하는 프랙티스가 경험적으로는 상당히 좋았던 것 같다. 아마도 이를 코드 검토를 시작하는 팀의 마지노선으로 잡으면 될 것 같다. 코드 검토는, 이 책에서 얘기하는대로, 작은 단위로 할 수록 효율과 정확성이 높아지는데, 작은 단위로 리뷰하는 문화를 정착시키는 것은 또 다른 과제다.
현재 팀에는 기술 리더라고 할만한 사람들이 몇 명 있는데, 팀의 한 파트를 책임지고 있는 나도 그 중의 한명이라고 볼 수 있다. 간단하게 말해서, 기술 리더는 기술 업무와 관리 업무를 수행해야 하는데, 둘 다를 수행하는 것은, 한가지만을 수행하는 것에 비해 절대 쉬운 일은 아니다. 가장 중요한 책임 중 하나는 역시 우선 순위의 조정이다. 업무의 목록은 팀원들 각자가 결정할 수 있지만, 우선 순위의 문제는 항상 기술 리더의 책임이다. 요즘 내가 생각하고 있는 것은, 우선 순위 결정을 주간 보고나 주간 회의와 같은 과정에 자연스럽게 연결해 프로세스화 하는 것이다.
‘예광탄 개발’은 일반적인 애자일 개발과 얼마나 크게 차이가 있는지 모르겠고, 굳이 ‘예광탄 개발’이라는 이름표를 달아주어야 하는지 의문인데, 이 글에서는 설명을 생략하도록 한다.
‘일반적인 문제와 해결 방법’은 분류하기 힘든 가이드라인을 모아놓은 부분이라고 볼 수 있는데, 그 중 ‘불한당 개발자’에 대한 대처 방법을 다룬 항목이 흥미로웠다. 고삐를 채울 수 없는 불한당의 경우, ‘불한당의 행동을 문서화하고, 반항적 행동을 문제 삼아 해고해야 한다’는 것이다. 그리고, ‘대부분의 경우엔, 문서화 과정을 시작하는 것만으로도 충격받아 제자리로 돌아온다’라고 한다. 실제로도, 문제를 일으키는 팀원의 경우, 문제점을 지적당하면, 그 근거를 제시하라는 답이 돌아오기도 한다. 이에 대한 정당한 답변은 다른 사람에게 어떻게 얘기했는가, 어떤 예절 바르지 못한 행동을 했는가 등이 아니라, 잘 문서화된 작업 목록 뿐이다. 이런 수단이 악의적으로 사용되어서는 물론 안되겠지만 말이다. 한편, Jeff Atwood의 ‘Dealing With Bad Apple‘이란 글에서는 불한당 또는 Bad Apple은 팀 전체에 악영향을 미치며, 어떤 사람의 능력은 발전할 수 있어도 태도는 변하기 어렵다는 이유로, 빨리 제거하는 방법밖에 없다고 얘기하고 있다.
이 책 전체에서 드러나는 실용주의적 태도 – 어떤 프랙티스가 절대적으로 옳다고 주장하기 보다는 적합한 것을 적용해나가자는 태도 – 는 상당히 마음에 드는 편이다.
내용이나 태도 뿐만 아니라, 구성 면에서도, 하나의 가이드라인마다 마지막에 ‘어떻게 시작하면 될까요?’, ‘제대로 사용하고 있는 걸까요?’, ‘경고 신호’와 같은 섹션을 두어, 이 책에 나온 가이드라인을 실제로 행동에 옮길 수 있는 지침으로 활용하기 좋게 만들어져 있다.
번역은 따로 언급할 필요가 없을 정도로 잘 되어 있는 편이다. 최근에 출판되는 해외에서 유명한 기술 서적들은 평균적인 번역 품질이 예전보다는 많이 좋아진 것 같다.
지난 번에는 Visual Studio 2008을 이용해서 Silverlight 2 애플리케이션을 개발하는 과정을 따라가봤는데, 이번에는 Scott Guthrie의 ‘First Look at Using Expression Blend with Silverlight 2’라는 튜터리얼을 보면서 Expression Blend를 사용해 Silverlight 2 애플리케이션을 개발해보았다.
Microsoft Expression 제품군은 디자인에 초점이 맞춰진 웹/데스크탑 애플리케이션 개발 도구인데, 그 중 Expression Blend는 WPF와 Silverlight 애플리케이션 개발 도구다. 현재 출시되어 있는 Expression Blend 2는 Silverlight 1 애플리케이션 개발만을 지원하기 때문에, Silverlight 2 애플리케이션을 개발하기 위해서는 Expression Blend 2.5 Preview (June 2008 버전)을 설치해야한다.
저번 글에서 언급했던대로, Expression Blend에서는 Silverlight 애플리케이션의 Interactive Design View를 제공한다. WYSIWYG 방식으로 디자인이나 컨트롤의 속성을 변경할 수 있도록 해준다. Visual Studio 2008을 이용할 때와 비교해, 손으로 마크업을 작성해주어야 하는 번거로움이 훨씬 줄어들었지만, 다음과 같은 단점들이 보인다.
첫번째는 코드 작성에 대한 지원이 부족하다는 것이다. 특히, Intellisense 지원이 없는 것으로 보인다. 따라서, Expression Blend로 디자인하고 Visual Studio 2008로 프로그래밍하는 것이 편리하다. 애초에 제품이 분화되어 있는 이유가 원래부터 디자이너와 개발자의 역할 분담을 위한 것으로 보이지만, Intellisense와 같은 기본적인 기능은 있어야 할 듯 하다.
두번째는 아직 Silverlight 기능에 대한 지원이 불완전하다는 것이다. 특히, Silverlight의 주요한 디자인 요소 중 하나인 스타일 지원이라든가, 애니메이션 지원이 아직 없다. 즉, 현재는 손으로 작성해야한다는 얘기다.
이러한 여러 상황들을 볼 때, Microsoft의 Silverlight 출시는 Microsoft 답지 않게(?) 급하게 서두른 감이 있다. 아직은 부족하나, 소프트웨어 개발 도구 제품에 있어서 뛰어난 역량을 보여온 Microsoft인만큼, 베타 버전이 아닌 정식 릴리즈를 기대해본다.
지난 4월 말에 최철호군과 함께 Introduction to Information Retrieval 스터디를 시작했습니다.
서로에게 설명하고 이해가 가지 않는 점을 토론하는 방식은 상당히 성공적이었습니다. 아무래도 스터디 상대가 검색 시스템을 비롯한 소프트웨어 엔지니어링 경험이 많다보니 적합한 방식이었던 것 같습니다.
실은 아직, 원래 목표로 했던 Chapter 9까지의 진행을 완료하지 못했습니다. 5월말까지 한 달 동안 Chapter 5까지 진행했으나, 서로의 사정으로 계속 미뤄지다보니 흐지부지 되어버렸네요.
스터디를 시작할 때는 Introduction to Information Retrieval 웹 사이트에 공개된 PDF를 제본해서 공부하고 있었는데, 그동안에 이 책이 출판되었고, 얼마전에 아마존에서 주문한 책이 도착했습니다. 역시 책이 도착하니 의욕이 좀 나서 Chapter 6, 7을 읽어버렸습니다. 일단 다음 주 정도에 최철호군을 한번 만나서 1차 완료를 해버릴 생각입니다.
스터디를 일단락 지은 다음에는 Web Search에 관련된 Chapter 19-21을 읽고, 본격적으로 Machine Learning에 관련된 Chapter 13-18을 읽을 생각입니다. 단숨에 하기는 힘들테지만, 적어도 연말까지는 이 책을 떼고 싶네요.
작년 12월에 Silverlight 1.0 애플리케이션 맛보기 개발에 대한 글을 쓴 적이 있다. 어제 새벽 2시 정도에 잠을 깨는 바람에 Silverlight 2 애플리케이션 개발을 위한 튜터리얼을 보면서 실제로 개발하는 과정을 체험해보았다.
Silverlight 1.0은 Javascript 만을 지원했고, GUI 애플리케이션 개발을 위한 라이브러리에 기본적으로 포함되어있는 레이아웃이나 컨트롤(위젯)들을 포함하고 있지 않았기 때문에, 이렇다 할 애플리케이션을 개발하기가 쉽지 않았다.
Silverlight 1.1 Alpha가 2007년 9월 경에 릴리즈 되었고, 2.0으로 이름이 바뀌면서 2008년 3월에 Beta 1, 6월에 Beta 2가 릴리즈 되었다.
Silverlight 2의 가장 큰 변화는 바로 작은 크기의 CLR을 포함함으로써 Javascript 외의 .Net 언어들, 예를 들어 C#을 사용해 Silverlight 바이너리를 생성할 수 있다는 것이다. 이에 따라, .NET Base Class Library이라든가 LINQ 등의 훌륭한 기능을 활용할 수 있게 되었다.
두번째는 레이아웃이나 컨트롤들이 추가되었다는 점이다. XAML 수준에서 컨트롤 확장이 가능하다는 것도 굉장히 놀랄만한 점이다.
세번째는 Web Services나 AJAX를 위한 WebClient, HttpWebRequest 뿐만 아니라, Socket 까지 지원하는 네트워킹 지원이다. 네트워크를 통해 받은 XML, JSON, RSS/ATOM Feed등을 처리하기 위한 클래스들이나 LINQ와의 연동 등도 훌륭하다.
Silverlight 2 애플리케이션을 개발하기 위한 좋은 튜터리얼은 Silverlight 홈페이지에도 링크되어 있는 Scott Guthrie의 튜터리얼이다. 이 튜터리얼은 Visual Studio 2008을 이용해 Silverlight 2 애플리케이션을 개발하는 과정을 설명하고 있다.
Visual Studio 2008에 Silverlight Tools for Visual Studio 2008을 설치하면,
아직은 부족한 면이 어느 정도 있는 편이다.
WYSIWYG 디자인은 Expression Blend에서 잘 지원이 되는 듯 한데 (그래서 Expression Blend 튜터리얼도 읽어볼 예정이다), 그동안 데스크탑 애플리케이션의 WYSIWYG 디자인이 주욱 Visual Studio에서 이루어져 온 것을 생각하면, 왜 Silverlight 애플리케이션의 WYSIWYG 디자인은 Visual Studio에서 지원되지 않는 것인지 궁금하다. 아직은 베타라서 그럴 수도 있다고 생각된다.
한편, Scott의 튜터리얼에서는 WatermarkedTextBox라는 컨트롤을 사용하는데, 얼마전에 릴리즈된 베타2에서 이 컨트롤은 제외되었고, 그 기능은 TextBox 컨트롤로 이전될 예정이라고 한다. 역시 아직은 베타 상태기 때문에, 개발 상의 변화가 베타 릴리즈 마다 꽤 크게 이루어지는 것을 볼 수 있다.
팀원 중 한 분이 팀 내에서 사용하는 장비 관리 도구를 Flex로 개발한 결과물을 보면서, 웹 애플리케이션의 귀결은 역시 RIA라는 것을 확인할 수 있었다. 현재의 소프트웨어 개발자가 HTML과 웹 언어를 사용해 웹 애플리케이션을 하나 쯤 개발할 줄 아는 것처럼, RIA 기술을 사용해 웹 애플리케이션을 뚝딱 만들어낼 수 있는 세상이 오는 것인가?