번역판을 읽었다. 원제는 ‘Writing Solid Code: Microsoft’s Techniques for Developing Bug-Free C Programs’. 대체로 C/C++ Programmer를 대상으로 한 버그를 줄이기 위한 프로그래밍 기술에 관한 유명한 책이다. 하지만, programming language에 한정되지않는 조언들도 있다. Steve Maguire의 Microsoft에서의 실제 경험을 바탕으로 지어진 책이고, 실제로 그의 경험들이 예시로 등장한다.
이 책에는 다음과 같은 조언들이 등장한다.
– Enable compiler warnings and pay attention to them. – Use assertions to validate your assumptions. – Don’t quietly ignore error conditions or invalid input. – For a complicated, critical algorithm, consider using a second algorithm to validate the first. (e.g. validate binary search with a linear search). – Don’t write multi-purpose functions such as realloc (it can grow memory, shrink memory, free memory, or allocate new memory — it does it all). – Check boundary conditions carefully. – Avoid risky language idioms. – Write code for the “average” programmer. Don’t make the “average” programmer reach for a reference manual to understand your code. – Fix bugs now, not later. – There are no free features; don’t allow needless flexibility (like realloc). – Ultimately the developer is responsible for finding bugs; he shouldn’t write sloppy code and hope that QA will find all his bugs.
[from Paul J. Mantyla’s comments in Amazon]
대체로 programming을 1-2년 정도 한 경험이 있는 사람이라면, 이러한 충고들은 대체로 스스로 익힐 수 있다. 시행 착오를 피하기 위한 책 정도가 될까. 오래된 책이라서 (1993년에 출판), 설명을 위한 예들 역시 오래된 감이 있지만, 충고들 자체는 여전히 유효하다. C/C++ programming job을 얻기 전의 학생들은 한번씩 읽어보면 좋을 듯한 책이다. 어느 정도 숙련된 programmer라면 부담없이 읽어볼만한 책이라서, 화장실에 두고 심심풀이로 읽는 것도 나쁘지는 않을 듯하다.
번역은 몇가지 용어의 번역이 모호해서, 원서를 찾아보기도 했지만, 무난한 편이었다. 번역서다 보니, 1-2일 정도만에 다 읽을 수 있었다. 조판 자체가 깔끔하지 못해서, 딱히 소장하고 싶은 마음이 들지 않는다. 번역서는 누군가에게 줘버리고, 원서만 가지고 있을 생각이다.
TDD는 XP와 함께 매우 유명한 프로그래밍 기술 중의 하나다. 어느 정도 TDD나 Agile software development methodology에 관심이 있는 사람이라면, “Test First”가 TDD의 가장 중요한 idiom을 알고 있을 것이다. ‘automated test를 먼서 작성하고, test를 동작하게 만들기 위한 가장 간단한 code를 작성하고, refactoring은 가능한 한 뒤로 미루라’는 것이 TDD의 기본이다.
이 책은 세 개의 파트로 나뉘어있다. Part I은 어떤 story (일종의 requirement)를 구현하는 과정을 TDD를 사용해서 보여주고 있다. Part II는 xUnit이라는 tool을 사용해서 TDD를 좀 더 편리하게 수행하는 것을 보여주고 있다. Part III는 TDD와 연관된 여러가지 pattern들을 정리해두었다.
TDD는 여러가지 이익을 가지고 있지만, 가장 마음에 드는 것은 test 설계부터 하기 때문에, 구현자의 입장보다 사용자의 입장에서 먼저 생각해보게 되고, 결국 interface의 품질이 더 좋아진다는 것이다. interface는 중요하지만, implementation은 그다지 중요하지 않다. implementation은 변경할 수 있고, interface는 그렇지 않을 가능성이 크기 때문이다. 이미 사용자들이 interface를 사용하고 있다는 이유로 대충 설계해놓은 interface를 개선할 수 없게되는 경우를 흔히 볼 수 있다.
번역도 되어있고 하니, 한번쯤은 읽어볼만한 책이다. 아마 집중해서 읽으면 2-3일이면 다 읽을 수 있을 듯 하다.
‘Introduction to Software Engineering’ 과목에서는 Object-Oriented Design을 가르친다. 간단한 정의와 함께, UML design 과정에서 use case로부터 object를 골라내서 class diagram을 그리는 법은 가르친다. 하지만, 아무도 object-oriented programming paradigm 뒤에 들어있는 생각을 가르쳐주지는 않는다. (물론, 다룰 주제가 많은 software engineering 과목에서 OOP를 깊게 설명하기는 어렵다.)
OOP language를 쓰는 것은 일종의 유행이다. 모두들 그 이유를 잘 알지도 못하면서 OOP를 선호한다. 심지어는 그것이 무엇인지도 모르면서 말이다. 사실, 나도 그런 사람들 중의 하나였고, C를 사용한 procedural programming paradigm에 익숙해지고 난 후, 주로 OOP language (C++, Java, Python, Ruby, …)를 사용하기 시작하면서, 계속 던지게 되는 질문은 OOP란 무엇인가, 대체 procedural programming paradigm보다 object-oriented programming paradigm이 무엇이 우월한가라는 것이었다.
‘Object Thinking’은 이러한 질문에 답변해주는 책이다. 즉, SE 과목에서 한두페이지의 페이지에 설명해놓은 것을 이 책에서는 300페이지에 걸쳐서 설명해놓은 책이다. OOP는 technique이 아니라 paradigm이다. 생각하는 방식은 누군가의 간단한 한마디 말로는 바뀌기 힘들다. (물론 그런 경우도 있다.) ‘Object Thinking’은 ‘object philosophy’, ‘object culture’란 말을 도입한다. 당연하게도, 사상(thinking)에는 철학(philosophy)이 전제되고, 문화(culture)가 따르고, 역사(history)를 가지기 마련이다. object thinking의 중심 원리(principle)들과 역사를 설명하고, 다른 philosophy와 culture와 대조를 함으로써 object thinking이 무엇인지가 조금씩 드러난다.
이 책에서는 단지 OOP가 무엇인지에 대해서만 다루고 있는 것은 아니다. OOP 외에도 software development의 여러가지 생각(thought)들을 object culture의 범주안으로 통합시킨다. 특히, XP와 같은 Agile software development가 여기에 해당된다. 따라서, 이 책에서 얘기하는 ‘object thinking’은 단지 OOP가 아닌 것이다.
또, 이 책에서 설명하는 OOP는 Booch를 중심으로 표준화된 전통적인 SE 진영의 OOP와는 조금씩 다르게 보인다. 여러번 책에서 언급되는 Smalltalk community 쪽(이를 공식적으로는 어떻게 지칭하는지 모르겠다.)에서 발전된 생각으로 보인다. 한가지 예로, OOP에 관한 여러 책들에서 object란 data와 algorithm의 결합이라고 지칭하지만, 이 책에서는 그러한 생각을 과감하게 거부한다. object란 behavior로 정의된다고 주장한다. 이러한 생각 한가지만으로도 object design에는 엄청난 영향을 미치게된다고 생각된다. (이 주제에 대해서는 나중에 따로 다뤄보겠다.)
아직 번역서가 없지만, 여력이 된다면, 또는 언젠가 번역이 된다면, 반드시 읽어보라고 추천해주고 싶은 책이다. 시간이 난다면, 이 책에서 인상 깊었던 생각들을 조금씩 블로그에 정리해볼까도 한다.
WebRSSAggregator는 RSS들을 수집, 통합하여, 웹을 통해 보여주는 어플리케이션이다. 즉, 흔히 말하는 RSS reader다. (전에도 이 사이트를 통해서 소개한 적이 있었으므로 더 자세한 내용은 생략하겠다.)
소프트웨어 개발의 진행 결과는 관리자에게 보고하고, 구현을 마친 요구 사항은 적어두면서, 개발을 하면서 발생한 design decison들을 기록하는 사람들은 거의 없다. 사실, 개발자의 실력을 키워주는 것은 그러한 작은 design decison이 모여서 이루어진 어떤 sense라고 생각한다. 이러한 과정은 물론 우리들의 뇌 속에서 자동으로 이루어지는 것이지만, 소프트웨어 개발을 하면서 드는 생각들을 정리해두는 것만으로도, 더욱 효과적으로, 긍정적인 피드백을 주리라고 생각한다.
Iteration 3
최근에는 적절한 feature들의 set을 모아서 기간을 정하고, 이를 하나의 iteration으로 개발하는 방식을 주로 사용하고 있는데, 이는 FDD에서 어느 정도 따온 방식이라고 볼 수 있다. WebRSSAggregator도 어느덧 세번째 iteration에 접어들었고, 이 iteration에서 구현할 feature들은 다음과 같다.
Refactoring
Model-View-Controller
Apply eruby template
Get method accepts Filter (rather than several get* methods)
More subscription information on subscription list, admin interface
“Mark read”
Content folding
Feature
Label operation: mark, unmark
More subscription information
retrieve channel information on addSubscription (title, link, description)
automatically update feed on addSubscription (only for Web interface?)
Documentation
rdoc documentation
Release
commit rubyforge
여러가지로 적어두었지만, 사용자 인터페이스를 정리하고, 코드를 MVC 기반으로 refactoring하는 것이 이번 iteration의 주요 목표다. 그리고, RubyForge에 WebRSSAggregator를 release하는 것이 이번 iteration의 최종 목표다.
View
어느 정도 기능들이 많아지고 사용자 인터페이스가 복잡해지면서, 가장 문제가 되는 것이 view와 logic의 분리다. 웹 어플리케이션의 View를 어떻게 설계할 것인가를 고민 중이다. MVC에 따르면, 여러 sub-view들 간에 hierarchy를 가진 view 구조를 선호하고 있다. 따라서, 각각의 subview를 (div element를 사용한) block으로 만들고 어플리케이션에 특화한 layout을 가진 main view가 이들을 조직화하고, 대부분의 formatting은 css에 맡김으로써, 간단한 (적어도 WebRSSAggregator에는 사용 가능한) View 정도는 깔끔하게 만들어낼 수 있지 않을까 생각하고 있다.
당장은 subview들 약간만 작업해놓은 상태다. (SimpleItemListView, FlatItemListView) 한가지 고민되는 것은 우리나라의 여러 portal에서 즐겨쓰는 table을 사용한 html page design에는 이러한 방식이 최악이 될 수도 있다는 것이다. 아직도 table의 div 대체 가능성에 대해서 명확한 대답을 보지 못했고, 가능하다면 이것을 증명해보고 싶기도 하다. (물론 WebRSSAggregator 따위로 될 리는 없지만)
이미 Rails 같은 MVC framework이 널려있고, MVC pattern이 꽤 흥행해왔기 때문에 Web App에서의 View에 관련된 내 고민들은 이미 대체로 해결된 별 쓸모없는 것일지도 모른다. 좀 더 살펴볼 예정이고, 조언도 환영한다. 어쨌거나 흥미로운 문제고, 이것 때문에 Web App Development에 대한 나의 관심이 요즈음 한껏 고양된 상태이다.
Accessing DB
Filter
DB로부터 data를 얻어올 때, business logic이 요구하는 내용에 따라 여러 method가 난립했었는데, filter라는 개념을 도입하여, 단순하게 정리했다. 예를 들어, 기존에는,
과 같이 단 하나의 method로 정리되었다. 참고로, Rails에서는 SQL 문의 WHERE 절에 들어가는 expression과 유사한 string을 filter로 사용한다.
ItemManager getItems(filterString)
이러한 filter들을 사용자 interface로 정리하는 것은 꽤 괴로운 일이었다. 직접 사용자의 선택을 모두 case by case로 처리하고 있는데, 다른 MVC framework의 Controller 디자인을 참조해보아야할 듯 하다.
Table Data Gateway/Active Record/Data Mapper
가장 처음 WebRSSAggregator를 만들었을 때는 class가 하나도 없었고, 단지 DB로 SQL 문을 query해서 data를 읽어온 후, html로 번역해서 뿌려주는 ruby script였을 뿐이었다. 초기 기능을 만들고나서 바로 class로 refactoring을 수행했고, 가장 먼저 건드린 곳이 DB를 access하는 부분이었다. 현재의 모습이 그 때 refactoring의 결과인데, 그러한 설계를 Table Data Gateway라고 부른다는 사실을 오늘 처음 알았다.
간단히 설명하면, DB table에 있는 data에 대한 모든 operation (주로 CRUD와 SELECT)을 수행하는 object다. 물론 이러한 operation들은 보통 business logic의 requirement에 따라 만들어지고, 각 operation이 보통 하나의 SQL 문을 나타낸다고 볼 수 있다.
WebRSSAggregator에서 ItemManager, SubscriptionManager, 그리고 CategoryManager가 모두 Table Data Gateway에 속한다. (‘Manager’라는 너무나 보편적인 이름을 지은 것은 후회해야할 일일 것 같다.)
ItemManager, SubscriptionManager, CategoryManager는 각각 attribute만을 가진 Item, Subscription, Category를 사용한다. 즉, Table Data Gateway는 passive data를 다루는 Controller object에 해당하는 것이다. “Object Thinking”에서는 이러한 설계가 Object-oriented paradigm의 철학과는 배치된다고 적극 말리고 있고, 이에 대한 대안을 찾고 있었는데, Rails의 문서를 뒤지던 중에, Active Record라는 pattern을 발견했다.
Active Record는 간단히 말해서, Controller object가 passive data들을 control하는 것이 아니라, Table 또는 Table의 row에 해당하는 object가 스스로 DB access를 수행하는 설계를 가지고 있다. 앞에서 말했던 “Object Thinking”에서의 충고에는 충실한 편이다.
당장은 Table Data Gateway인 ItemManager, SubscriptionManager, CategoryManager의 responsibility를 현재는 passive data에 불과한 Item, Subscription, Category로 이전시켜, Active Record로 만들 생각이다.
DB Access에 관련된 pattern에는 Table Data Gateway와 Active Record외에도 Data Mapper가 있다. Data Mapper는 object와 relational database 사이에서 OR mapping을 수행해주는 object다. 따라서, 이 경우 object는 DB Access에 관해 신경을 쓰지 않을 수 있게 된다. business logic과 DB를 access하는 logic을 적극적으로 분리하는 pattern이라고 볼 수 있다.
PHP programming language에 대한 어떤 비판 중에는 HTML 안에 code를 embed할 수 있기 때문에, presentation과 code의 분리를 방해한다라는 주장이 있다. asp, jsp 등이 web language로서 보편화된 것을 보면, 그 주장이 사실이라고 하더라도, 분명 그러한 단점을 넘어서는 장점이 있기때문일 것이다.
개인적인 생각으로는 code를 HTML에 embedding할 수 있는 것은 매우 편리하다. 위에서 살짝 언급했듯이, subview들을 block등으로 적절히 나타낸다고 하더라도, 전체 layout을 나타낼 때 code를 사용해 HTML을 generation한다면 매우 이해하기 힘들고 수정하기도 힘든 코드만 대량으로 생산해낼 뿐이다. 하지만, code embedding과 HTML을 적절히 조화시키면 깔끔한 View 코드를 생성할 수 있다.
이러한 코드를 보면 그러한 비판은 정말로 유효한 것 같다. (실제로는 더욱 심할테니!) 하지만, 이것은 언어 자체의 문제나, HTML에 code를 embedding 시킬 수 있는 기능 자체의 문제가 아니다. 이러한 코드를 쓴 사람은 어떤 프로그램을 짜더라도 엉망으로 짤 것이다. 프로그래머로서의 자질 자체가 문제인 것이다.
WebRSSAggregator에도 이러한 생각을 증명하기 위해서 eruby를 적용해보았다. 현재까지 만들어진 sub-view들을 제외한 View는 전부 HTML과 embedding된 ruby code로 되어있다. 가능한 한 대부분의 View는 클래스화 하겠지만, 전체 페이지 모두를 클래스화할지는 아직 의문이다.
To Be Continued…
WebRSSAggregator에서의 MVC 구현이 좀 더 진척된 미래의 어느 시점에 다음 편이 나오지 않을까 싶다.
“More Effective C++”와 “Effective STL”을 번역하신 곽용재님이 번역작업 중이시고, 초고를 탈고하셨다고 한다. The C++ Programming Language는 C++의 창안자인 Bjarne Stroustroup이 쓴 책인 만큼 권위있고, 자세하며, 잘 쓰여진 책이다. (Books for Software Development 참조) C++ 을 배우는 사람들이 C++ 책을 추천해달라고 할 때, The C++ Programming Language를 추천해줄 수 없었던 가장 큰 이유가 번역이 되지 않았다는 사실이었는데, 앞으로는 대답이 달라질 수 있을 듯하다.
“Rapid Development”를 번역하신 박재호님이 번역작업중이시다. 이 책은 원래 개발자들 사이에 매우 유명한 “Joel On Software”라는 Joel Spolsky의 홈페이지 내용을 책으로 엮은 것이다. 나는 송민철 팀장님이 알려주신 “The Joel Test”를 통해서 Joel On Software를 알게되었는데, 이 후로 계속 RSS를 구독중이다. 아쉽게도, 원서를 아마존을 통해서 이미 사버려서, 번역판을 살 일은 없을 것 같지만, 이런 좋은 책이 번역된다는 것은 매우 기쁜 일이다.
PHP, which stands for “PHP: Hypertext Preprocessor” is a widely-used Open Source general-purpose scripting language that is especially suited for Web development and can be embedded into HTML. Its syntax draws upon C, Java, and Perl, and is easy to learn. The main goal of the language is to allow web developers to write dynamically generated webpages quickly, but you can do much more with PHP.
즉, PHP는 general-purpose이긴 하지만, Web development를 위해 특화된 언어이며, 쉽게 배울 수 있고, 빠르게 개발할 수 있는 (agile) 언어라는 점을 선언하고 있다.
PHP의 역사를 보면 왜 PHP가 이러한 철학을 가지고 있는지는 확연하게 드러난다. PHP의 원래 이름은 “Personal Home Page Tools”였으니 말이다.
Why PHP?
왜 PHP 였는가? 왜 여러 language alternative들 중 PHP가 “Web language”의 자리를 차지했는가? 답은 PHP 언어의 철학안에 있다. PHP는 웹 개발에 특화되어있었으며, 쉽게 배울 수 있고, 빠르게 개발할 수 있으며, open source였기 때문이다. 언어 외적인 중요한 factor 중 하나는 PHP가 빠르게 성장하고 있던 Apache의 module 기능을 처음으로 적용한 middleware solution이라는 것이었다. (“처음으로” 라는 사실은 중요하지 않다. “초기에”라는 말이 적합할 것이다. 3개월 정도 후에, Perl도 modperl을 내놓았기 때문이다.)
C# Attribute를 사용해 contract/interface를 명시하는 방식은 이미 최근 RPC 관련 programming model에서 일반적인 trend라고 볼 수 있고, ServiceHost는 일종의 Container라고 볼 수 있을 것 같다. 특기할만한 점은 C# Generics을 이용해 container와 implementation을 결합했다는 점 정도. 여러 end point를 추가할 수 있는 점도 여러 Transport를 제공하는 Indigo의 특성을 잘 드러내주는 점이라고 할 수 있을 듯 하다.
Beta service 상태이던 MSN Search가 2월 1일자로 open 되었습니다. 원래 있었는지는 모르겠지만, MSN portal에도 적용되었나봅니다. 밑에 있는 article에서 언급된 특정 사이트로 링크한 페이지를 찾는 기능도 실험해보았습니다. “link:www.lastmind.net” 식으로 검색하면 되는데, 제가 URL을 넣은 comment들이 주루룩 나오는군요.