Software Development

Is PHP A Bad Programming Langauge? (Part 2)

Hatred for PHP

대부분의 사람들은 PHP가 표방하는 PHP의 철학에 동의한다. 그렇다면 무엇이 싫단 말인가? 웹 검색을 통해서 다음과 같은 글들을 발견할 수 있었다.

이 사람들은 PHP를 미워하고 있다. 그 이유는? 어느 정도 유효하고 중요한 내용들만 내 생각들과 함께 정리해보았다.

Language Syntax

  • No namespaces: 어느 정도 복잡한 product를 만들 때, 불편한 점 중의 하나는 함수 이름이나 변수 이름이 중복되는 것이다. 이 문제에 대한 해결책으로, 모든 함수나 변수들의 이름에 prefix를 붙여서 namespace를 구분하거나, 클래스를 namespace의 대용으로 사용하는 방법이 있다. C와 같은 다른 언어들을 생각해보면, 분명히 namespace가 없이도 커다란 프로덕트를 만드는 것은 가능하다. 하지만, 최근에 나온 대부분의 언어가 namespace를 가지고 있음에도 불구하고 PHP 5에 namespace가 들어가지 않은 것은 상당히 아쉬운 부분이다.
  • Arrays are ordered maps: PHP의 array는 기본적으로는 key, value pair의 집합인 ordered map이다. PHP의 array는 이러한 map의 용도 뿐만 아니라 여러 용도로 전용된다. integer를 key로 하는 전통적인 array를 비롯하여, list, queue, stack 등으로 사용될 수 있다. 이러한 사실은 array function들을 ë³´ë©´ 알 수 있다. 언어가 단순해지고, 여러가지 데이터형으로 활용함으로써 얻는 편리한 점도 있겠으나, 프로그래머가 array라는 데이터형에 대한 명확한 모델을 머리속에 그리지 못하게 하고, 또한 프로그래머가 실수를 할 가능성을 높힌다는 측면에서 그리 좋지 못하다고 생각된다. 많은 언어들이 array와 map을한다. 하지만, 그렇다고 string 만으로 array를 지원하는 언어들을 무시할 수는 없다. 어떤 데이터형을 지원하는가 하는 문제는 언어의 단순성과 프로그래머의 편이성 사이의 trade-off 문제라고 생각한다. 어떤 언어가 어떤 데이터형을 지원하느냐는 ê·¸ 언어의 철학에 달린 일이고, 정답이 있는 것은 아니다.
  • Does not enforce the declaration of variables: PHP는 선언 또는 정의되지 않은 변수이더라도 참조가 가능하다. (물론 warning은 발생한다.) "<? print $undeclared_variable; ?>"라는 PHP 코드와 "print undeclared_variable"이라는 Ruby 코드를 실행해보라. PHP에서는 아무렇지 않은 듯이 조용히 실행되지만 Ruby에서는 "undefined local variable or method"라는 에러가 발생한다. 비교적 작은 프로그램, 모듈, 또는 함수에서는 큰 문제가 되지 않지만, 코드가 길어지고 복잡해질 수록 버그를 발생시킬 가능성이 높아지고, 이 버그를 발견하는 것도 힘들어진다. PHP에서는 옵션을 통해 정의되지 않은 변수 접근에 대한 경고를 켤 수 있다.
  • No real references: reference가 아니라 name alias일 뿐이기 때문에 여러가지 문제가 발생한다. http://www.php.net/manual/en/language.references.php
  • No chained method call: $foo->bar()->op() 같은 문법이 불가능했었다. PHP 5에서 가능해졌다.
  • No closure, not even anonymous functions
  • shortcut behavior: 다른 언어들과는 달리 shortcut의 결과값이 boolean 값이다.
  • call-time pass-by-reference deprecation: PHP에서 reference를 사용하는 문법은 매우 이상했다. function을 정의할 때 파라미터에 reference임을 나타낼 수도 있고, 실제로 호출을 수행할 때도 reference임을 나타낼 수 있었다. 이 점은 기존 PHP 문법이 상당히 불완전함을 나타내는 증거라고 ë³¼ 수 있는 것 같다. (예를 들어, function 정의의 파라미터에도 reference라고 명시하고, 호출 시 아규먼트에도 reference라고 명시한다면 어떻게 될 것인가. reference의 reference? 답은, 그냥 reference다.) 결국은 호출 시 reference 명시는 deprecated 되었다. 문제는 이 deprecation으로 기존에 할 수 ì
    žˆì—ˆë˜ 일을 할 수 없게 되어버렸다는 것이다. PHP 5에서는 모든 variable을 reference semantic을 가지도록 바꾸었기 때문에 더이상 이런 문제는 없을 것이다.

Language Implementation

  • Template: 대부분의 언어들은 templating을 언어의 구현과 분리해놓지만, PHP의 구현에는 완전히 합쳐져있다. 웹 어플리케이션의 규모가 커지면서 프리젠테이션과 로직의 분리가 중요해진 지금 시점에는 그다지 좋지 않은 방법이다.
  • Register Globals: Register Globals는 CGI를 통해 들어오는 리퀘스트 변수들을 전역 변수로 만들어주는 기능이다. namespace를 가지지못한 PHP로서는 전역 namespace를 더럽히는 것은 엄청나게 해로운 일이다. 물론 여기에는 "웹 프로그래머의 편이"라는 언어가 만들어지던 당시의 고려가 담겨있다. 하지만, 웹 어플리케이션의 규모가 커지면서 이 기능은 PHP를 해치는 기능이 되어버렸다. 최근에는 이 기능을 켜고 끌 수있는 옵션의 기본 값이 "끄는 것"으로 바뀌었다.
  • Bad recursion support: 스피드를 위해서 stack에 저장하는 데이터가 많기 때문에 recursion에 좋지 않다.
  • Not thread-safe: 구현을 ë³´ë©´ thread safety를 위한 노력을 하고 있으나, 실제로 thread-safe 하지는 않다.
  • Magic quotes: Magic quotes는 PHP가 사용하는 데이터에서 특정 문자들을 자동으로 escaping 해주는 기능이다. 프로그래머가 직접 하더라도 크게 불편하지 않은 작업을 굳이 자동으로 해주어서 복잡도를 증가시키는 것은 좋지 않은 기능인 것 같다.

Standard Library/3rd-party Library/Framework

  • Inconsistency: PHP에서 기본으로 제공되는 라이브러리에 들어있는 함수들의 이름이나 파라미터들은 상당히 일관성이 없다. 다음 링크 참조.
  • no crucial XXX library: html parser, MIME builder, WWW library, consistent database API, gd를 제외한 graphics library가 없다는 것을 불만스러워하고 있다. PEAR에서 어느 정도 해결되기를 기대해본다.
  • no CPAN: 현재는 PEAR가 공식적인 extension repository가 되었으나, CPAN 처럼 사용하기에 편리한 것은 아니다.

People

  • Knowledgeable people are in a serious minority: 외국의 PHP 커뮤너티조차도 수준이 낮다는 지적을 많이 받고 있는데, 내가 보기에는 국내의 PHP 커뮤너티ë
    „ 크게 다르지 않은 것 같다. 가장 유명하다는 PHPSCHOOL에 가보라.

Is PHP A Bad Programming Langauge? (Part 2) 더 읽기"

Refactoring traditional web application with MVC pattern (Part 1)

Introduction

어떤 practice가 보편화되어있고 그것을 보조하는 툴이나 생각의 장치들이 잘 발달되어 있다면, 오히려 그 practice의 장점이 무엇인지 파악하는 데에는 방해가 되기도 한다. 어떻게 보면, 생산성을 높히고자 하는 우리의 노력이 때로는, 각 개인의 능력을 키우는 데에는 방해가 될 수도 있는 것이다.

예를 들어, 잘 만들어진 소프트웨어 프로세스 환경에만 익숙한 개발자는, 그러한 프로세스가필요없다고 주장하는 사람에게, 그것이 왜 필요한지 제대로 설명하지 못할 것이다.현대의 특정 프로그래밍 언어에만 익숙한 사람은, 자신이 활용하고 있는 수많은 언어적 장치들의 이점을 제대로 이해하고 있지 못할 가능성이 높다.

마찬가지로, 잘 만들어진 Model-View-Controller(이하 MVC) 프레임워크에만 익숙한 사람이라면, 그 패턴이 가지고 있는 유용성이나 의미를 발견하지 못할 가능성이 높다. 대부분의 웹 어플리케이션 개발자들은, 프리젠테이션과 로직이 뒤섞인 기존의 웹 어플리케이션에만 익숙하거나, MVC 프레임워크 웹 어플리케이션에만 익숙하다. 기존의 웹 어플리케이션이 MVC를 사용함으로써 어떤 점에서 좋아질 수 있는지는 전자나 후자의 프로그래머들 모두 알지못할 가능성이 높다.

이 글의 목적은 기존의 웹 어플리케이션에 MVC 패턴을 적용하면서 리팩토링하는 과정을 보임으로써, MVC 패턴의 유용성을 재발견하는데 있다.

Galaxy

Galaxy는 개인적으로 개발중인, RSS를 주기적으로 받아와서 사용자에게 보여주는 웹 어플리케이션이다. 이 글에서 예로 들 부분은 Galaxy의 admin 모듈이다. 이 모듈의 기능은 다음과 같다.

  • 사용자는 자신이 구독할 RSS Subscription을 등록, 삭제하거나 조회, 수정할 수 있으며,
  • 각각의 Subscription에는 Category를 할당할 수 있다.
  • 이 Category 역시 등록, 삭제, 조회, 수정될 수 있다.
  • 그리고, 사용자는 전체 Subscription을 수동으로 업데이트할 수 있다.

Galaxy in traditional-web-application style

일단 Galaxy의 첫번째 버전에서는 Subscription을 등록하는 기능만 제공하기로 결정했다고 가정해보자. 자, 먼저 Subscription을 등록하는 폼을 보여주고 사용자가 정보를 입력하고서 폼을 submit하면 Subcription 정보를 DB에 저장하는 로직을 처리하는 어플리케이션을 생각해보자.

자신을 Perl CGI나 PHP, ASP 등을 사용하는 웹 어플리케이션이 막 퍼지기 시작하던 시절의 웹 프로그래머라고 가정해보자. 필요한 기능은 그다지 많지 않고 로직도 단순하다. 그 시절에 방명록 따위를 심심풀이로 짜본 경험이 있다면, 금방 감이 올 것이다. 파일 이름은 admin.rb라고 하자. (Galaxy는 Ruby 어플리케이션이므로, 예제 역시 Ruby 언어를 사용한다. 간단한 템플리팅(templating)을 위해 eruby를 사용한다고 가정하자.) 웹어플리케이션이라는 신기술을 다룰 줄 아는 우리가 생각해낸 코드는 아마 다음과 같을 것이다.

Traditional-web-application-style Galaxy

즉, ‘mode’ 리퀘스트 파라미터가 없을 때는 Subscription 등록을 위한 양식(form)을 보여주고, 이 양식이 submit되면 ‘mode’ 리퀘스트 파라미터가 설정되어 Subscription 등록을 처리하는 방식이다.

이 코드에 어떤 문제가 있는가? 그렇지 않다. 문제는 없어 보인다. Subscription 등록이라는 단순한 기능을 수행하는 목적의 어플리케이션으로서 이 이상의 무언가를 필요로 한다면, 그게 더 이상한 것이다.

이제 다시 질문을 하겠다. 이 코드에 어떤 문제가 있는가? 그렇다. 이 어플리케이션은 현재는 Subscription 등록이라는 단순한 기능밖에 없지만, 앞으로 위에서 언급했던 여러 기능들을 모두 넣어야하는 미래를 가지고 있다. 자 여기서 약간의 상상력이 필요하다. 이 기능들을 하나씩 추가할 때마다, 리퀘스트 파라미터에 따라 분기하는 if-else-end 구문은 엄청나게 길고 복잡해져갈 것이다.

그리고, 이 어플리케이션은 웹 어플리케이션임을 기억해야한다. 위의 예에서는 html이 별로 사용되지 않았지만, 실제 서비스에 적용하기 위해 웹 디자이너가 던져준 화려한 페이지의 html 마크업은 훨씬 복잡할 것이다. 기존의 웹 어플리케이션은 프리젠테이션을 위한 html 마크업과 도메인 로직을 위한 코드가 복잡하게 뒤섞이는 경향이 있다.

웹 어플리케이션의 또 한가지 중요한 특징은, 로직의 변경 빈도와 프리젠테이션의 변경 빈도가 현저히 차이난다는 것이다. 커다란 리뉴얼부터 자잘한 수정까지 html 마크업은 코드에 비해 자주 변경된다. 문제는 html 마크업과 코드가 뒤섞여있음으로 인해, 잦은 html 마크업의 변경은 필연적으로 코드, 그 중에서도 가장 중요한 도메인 로직의 버그 가능성을 낳게 된다.

결국, 우리에게는 프리젠테이션과 도메인 로직의 분리(decomposition)가 필요하다.

Extracting domain objects

위의 예에서 도메인 로직은 어떤 부분인가? 바로 "Subscription을 등록하는 것"이다. 도메인 로직을 프리젠테이션으로부터 분리해내는 방법에는 여러가지가 있겠지만, 우리는 객체지향언어를 사용하고 있으므로, 도메인 로직을 도메인 객체(domain object)의 형태로 분리해내는 방법을 채택하자. "Subscription을 등록하는 것"에서 도메인 객체는 무엇일까? 바로 Subscription이다.

Subscription 객체를, 우리가 사용하고 있는 Ruby로 표현하기 위해서는 클래스를 사용하면 되겠다.

Subscription class as domain object

그리고, 기존 코드는 Subscription 객체를 사용하도록 바뀔 것이다.

Using Subscription object

이로써 원래 코드에 있던 도메인 로직 부분을 몽땅 하나의 클래스로 분리해낼 수 있게 되었다. 변경된 admin.rb에는 클래스 하나와 훨씬 간단해진 나머지 코드가 남게되었다. 또한, 프리젠테이션을 자주 변경해도 DB에 도메인 정보를 저장하는 걸 빠뜨리거나 할 가능성은 훨씬 줄어들게 되었다.

MVC 패턴에서는 도메인 정보를 나타내거나 그것을 처리하는 역할을 하는 도메인 객체를 Model이라고 부른다.

Refactoring traditional web application with MVC pattern (Part 1) 더 읽기"

MovableTypeWriter with XStandard

제가 만든 MovableType의 클라이언트인 MovableTypeWriter를 약간 손봤습니다. 에디터로 사용하던 mshtml전에 한번 언급했던 XStandard로 바꾸었습니다.

MovableTypeWriter with XStandard (Visual editing)

MovableTypeWriter with XStandard (XHTML editing)

바꾸는 작업은 그리 어렵지 않았습니다.XStandard Lite를 설치하는 것부터, 프로젝트에 XStandard COM component에 대한 Reference를 추가해주고 10라인 정도의 코드를 수정하는 작업까지 어저께 오전 1-2시간 만에 끝났습니다. 그리고, Doodle Bug부터 지금 쓰는 글까지 모두 새로운 MovableTypeWriter를 사용해서 작성했죠. XHTML 1.0 표준에 호환되는 코드를 생성하는 것을 확인하니 매우 기분이 좋더군요.

어떤 분들은 이 블로그의 오른쪽 메뉴바에 XHTML 1.0 표준 호환 배너가 달렸다는 것을 눈치채셨는지도 모르겠습니다. (무려 XHTML 1.0 Strict 입니다.) 배너에 해당 페이지의 Markup Validation Service가 링크되어있으니, 호기심이 많으신 분들은 테스트해보셔도 되겠습니다. (그러고보니 XHTML 1.1이 아니라 왜 XHTML 1.0일까요? 기본 템플릿의 Doctype이 XHTML 1.0으로 되어있었던 모양입니다. 이것도 손봐야겠군요.)

덤으로 MT의 템플릿과 최근 글 내용들이 표준에 호환되도록 좀 손봐주었습니다. 표준에 호환되지 않는 예전 글들이 많아서, 손으로 일일이 바꾸기 보다는, 적당한 툴을 사용해서 한번에 손봐야할 것 같습니다.

MovableTypeWriter with XStandard 더 읽기"

프로젝트 관리 도구의 사용성

회사에 다닐 때, 몇몇 프로젝트 관리 도구들 – Microsoft Project나 dotproject 같은 웹 기반 도구들을 사용해보았는데, 쓸데없이 너무 복잡하거나, 필수적인 기능이 빠져있는 경우가 많았을 뿐만 아니라, 사용하기가 너무 불편했다.

dotproject

XP 방법론이나 TDD 같은 practice를 보면서, 그러한 방법론에 잘 들어맞는 툴이 없다는 것도 느낄 수 있었다.

예를 들어, XP 방법론에서는 User Story로부터 요구사항을 수집하고 구현해야할 기능들을 찾아낸다. 그리고 이러한 기능들 중, 특정 기간 내에 개발할 기능들을 골라낸다. 기능별로 여러 사람들에게 분배되고, 기능을 구현하면서 또는 사용자의 피드백을 통해 추가적으로 찾아낸 기능들은 다음번에 구현할 기능으로 넣어둔다. 이러한 프로세스를 따라가면서 기존의 프로젝트 관리 도구를 사용해보라. 페이지를 이리저리 왔다갔다 해야하고, 불필요한 수많은 정보들을 입력해야한다. 방법론이 강조하는 프로세스를 따라가면서, 프로젝트 관리자나 개발자가 프로세스 상에서 발생하는 정보를 자연스럽게 입력하고 조회하는 것은 매우 불편하다.

한마디로, 방법론 상의 프로세스와 프로젝트 관리 도구의 사용성은 잘 들어맞지 않는다. 하지만, 복잡한 프로젝트 관리 도구들을 사용하더라도 위의 프로세스에서 발생하는 정보들을 모두 표현할 수는 있다. 그렇다면 무엇이 문제인가?

그 이유는, 여러가지 방법론 사이의 중요한 차이점이 그것들이 가지고 있는 정보가 아니라, 정보가 전달되는 방법과 방향의 특성 – 프로세스에 있기 때문이다. 우리에게는 프로세스의 흐름을 잘 반영하는 도구를 찾아보기가 힘들다. 만약 이러한 요구를 잘 반영한 도구가 있다면, 요구의 반영은 잘 신경써서 만들어진(crafted) 사용자 인터페이스의 형태로 나타날 것이다. 이러한 점에서, 프로젝트 관리 도구의 불편함은, 도구의 기능적인 면과 도구가 다룰 정보에만 치중하고, 사용자 인터페이스 즉, 도구를 다루는 방법은 무시하는 프로그래머들의 일반적인 경향이 반영된 결과일런지도 모른다.

한편, 기존의 프로젝트 관리 도구들은 방법론의 특성을 제대로 반영하지 못할 뿐만 아니라, 그러한 방법론이 실무에 적용되면서 발생하는 변형들도 잘 반영하지 못한다.

프로세스 상의 약간의 변형이나, 필요한 정보 자체의 변형이 발생하는데, 대부분의 프로젝트 관리 도구는 이러한 변형을 잘 반영할만한 유연성을 갖추고 있지 못하다. 반대로, 특정 방법론(이른바 표준 방법론)에 잘 맞춰져있는 도구에 자신들의 방법론을 맞추는 것은 완전히 어불성설이다. (이는 많은 사람들이 저지르는 실수중의 하나이다.) 프로젝트의 환경에 따라 방법론은 적절하게 변형되기 마련이다.

nohmad 옹 최근의 웹 어플리케이션에 관한 글에서 소개된 sproutliner는 작업 관리를 위한 도구다. sproutliner는 자기가 원하는 대로 작업 항목의 필드를 늘리거나 줄일 수 있는데, 위와 같은 프로젝트 관리 도구상의 필요를 반영하는 것이 아닐까. 물론 작업 관리라는 한정된 기능을 수행하고 있고, 정보의 변형에 있어서의 요구만을 반영하고 있어서, 아쉬운 점이 좀 남는다.

sproutliner

또, 어떻게 보면, 방법론에 무관하게 유연한 도구를 만들고 싶다는 목적을 달성하기 위해서는, 커다란 단일한(monolithic) 도구가 아니라, sproutliner처럼 서로 통신할 수 있고 조합할 수 있는 작은 단위의 도구들의 형태를 가져야할 지도 모른다.

기회가 된다면, 내 주변의 – 나 자신 또는 나를 포함한 팀의 – 방법론에 잘 들어맞는 프로젝트 관리 도구를 만들어보고 싶다.

프로젝트 관리 도구의 사용성 더 읽기"

Profiling Ruby program

루비 프로그램 맨 위에 다음과 같이 적어주면 된다.
(여기를 참고.)

require ‘profile’

또는 ruby의 command-line parameter로 ‘-rprofile’을 줘도 된다. (역시 profile module을 맨처음 require하는 의미)

이런 방식으로 profiler와 함께 실행시켜보면 다음과 같은 결과를 볼 수 있을 것이다.

%   cumulative   self              self     total
time   seconds   seconds    calls  ms/call  ms/call  name
35.56     0.16      0.16       86     1.86     7.44  Kernel.require
8.89     0.20      0.04       57     0.70     1.58  SubscriptionManager#constructSubscriptionFromRow
8.89     0.24      0.04      203     0.20     0.30  Kernel.puts
6.67     0.27      0.03       23     1.30    10.00  Array#each
6.67     0.30      0.03        7     4.29    12.86  Mysql::Result#each
6.67     0.33      0.03      728     0.04     0.04  Array#[]
4.44     0.35      0.02      407     0.05     0.05  IO#write
4.44     0.37      0.02       18     1.11     1.11  Mysql#initialize
2.22     0.38      0.01       92     0.11     0.11  Kernel.==
2.22     0.39      0.01       80     0.13     0.13  String#==
2.22     0.40      0.01       13     0.77     0.77  Module#attr_accessor
2.22     0.41      0.01       18     0.56     0.56  Mysql#query
2.22     0.42      0.01      119     0.08     0.08  Fixnum#to_s
2.22     0.43      0.01       31     0.32     0.32  Module#attr_reader
2.22     0.44      0.01       22     0.45     0.45  Module#alias_method
2.22     0.45      0.01       57     0.18     0.18  Subscription#initialize

한편, eruby interpreter랑은 좀 이상하게 동작하는 (무한루프) 문제가 있어서, eruby tag를 모두 빼고 테스트해야만 했다. 이 문제는 좀 더 살펴보아야겠다.

Profiling Ruby program 더 읽기"

Rich Internet Application 기술

인터넷 어플리케이션의 세상을 살아가는 소프트웨어 개발자로서, 놓칠 수 없는 흐름이, RIA(Rich Internet Application) 기술의 흐름이다. ActiveX가 기술적으로 좋은 선택이 아님에도 불구하고, 우리나라에 ActiveX 기술이 보편화된 것은, 바로 RIA 기술에 대한 요구의 반영이라고 볼 수 있다.

DHTML이나 Gmail에서 도입된 후 유행하고 있는 ajax, Flash 등도 모두 이러한 흐름의 한 갈래라고 볼 수 있다. (nohmad님의 flickr-throws-flash-adopts-dhtml 참고)

또한, 이러한 frontend 기술들을 backend 기술과 조합한 RIA 솔루션을 제공하는 회사들도 있다. (일전에 #perky 채널에서 rapzzard님이 알려주신 것들을 정리해보았다.)

Rich Internet Application 기술 더 읽기"

UML Fever

얼마전에, ACM Queue에 올라온 Death by UML FeverUML Fever: Diagnosis and Recovery를 읽었다.

UML을 사용하면서 발생하는 여러가지 부정적인 현상들을 UML Fever라고 표현하고 있다. 이 글을 쓴 Boeing Company의 Alex Bell은 UML Fever의 궁극적인 원인은 그 기술이나 프로세스를 선택하고 적용해야하는 개인의 경험 부족에 있다고 본다. 쓸데없이 메타포를 남발해서 읽기가 굉장히 힘들지만, 요약하면 다음과 같은 현상들로 나타낼 수 있다.

  • 자신의 프로그램에 어떠한 기술과 프로세스가 적합한지 평가하는 것이 아니라, 다른 사람이 다른 프로그램에서 사용한 것들 그대로 받아들이는 행위.
  • UML 다이어그램만 있으면 자동적으로 소프트웨어를 개발할 수 있고, UML이야말로 모든 소프트웨어 공학의 해결책이다라는 생각.
  • UML artifact를 많이 가지고 있을 수록 가치가 증가한다는 생각.
  • 쓸데없이 너무 많거나 상세한 UML artifact를 만들어내는 것을 소프트웨어 개발 프로세스나 프레임워크 혹은, UML 그 자체의 탓으로 돌리는 행위.
  • 생산성의 향상을 이유로, 자신의 프로세스에 맞지도 않는 비싼 UML 툴을 구입하는 행위.
  • 이미 불필요해진 UML artifact를 버려서는 안된다고 생각하고, 비용을 감수하면서 관리하려는 경향.
  • 아무런 목적이 없이 UML을 만드는 행위.
  • 세분화된 기능적 decomposition을 use-case로 만들려는 경향. (모델을 단순화하려는 목적을 잃고, 오히려 더욱 이해하기 힘들게 만든다.)
  • UML 다이어그램을 극단적으로 상세하게 만드려는 욕구. (어떤 것이 중요하고 중요하지 않은지 판단하기 위해서는 코딩 경험이 중요하다.)
  • 상세한 디자인 요소들을 포함하는 거대한 UML 모델을 만드는 행위. (코드 없이, 모든 정보를 표현할 수 있다는 생각.)
  • UML 디자인 모델과 코드로부터 reverse-engineer한 구현 모델의 차이를 인지하지 못하는 것
  • 모든 프로젝트 구성원들이 경험에 상관없이 교환가능하다는 생각.
  • 전문적인 기술이 없는 사람을 그 기술이 필요한 position에 기용함으로써, 조직 전체가 그 사람의 practice를 best practice로 여기게 되는 현상.
  • 간단한 디자인 툴이나 언어 문법에 대한 클래스에 사람을 보내고서, 전문가로 될 것이라고 기대하는 행위.

UML Fever의 여러가지 현상은 단지 UML에 한정되는 것이 아니라, Software development에서 사용하는 모든 기술, 더 나아가서는 모든 기술에 적용된다고 생각한다. 어떤 기술에 대한 제대로 된 지식이나 경험의 부족은, 그 기술이 어떠한 해결책에 적합한지를 제대로 평가하지 못하게 만들고, 그 기술에 대한 맹신이나 잘못된 적용을 낳는 것 같다. 이와 비슷한 얘기를 삼색볼펜초학습법과 소프트웨어 엔지니어링이란 글에서도 언급을 했었다.

UML Fever 더 읽기"

Galaxy 0.1.0 Released!

Galaxy 0.1.0 Relased!

The first release of Galaxy: Web-based RSS Feed Aggregator! This release includes basic functionalities of Galaxy. If you’re very serious about subscribing RSS in web, just try it.
WARNING: I’m aware that it has crude look and quite messy installation steps. But, I promise next release will address these problems.

릴리즈를 계획한 것은 꽤 오래전인데, 학업이 바쁘다보니 차일피일 미루다, 드디어 Galaxy 0.1.0을 릴리즈 했습니다. 곧 Rubyforge 탑에 올라오겠죠.

결함도 많고 마음에 안드는 것도 많이 있지만(코드는… 물론 엉망입니다.), 일단은 릴리즈하고 피드백 받으면서 개선해나가는 것이 좋을 것 같습니다. Eric Raymond의 The Cathedral and the Bazaar를 읽어보신 분이라면 이해하시리라고 생각합니다.

그러한 결함 중 한가지 예를 들면, 설치 방법이 너무 복잡한 문제가 있는데요. crontab 사용을 포기한다든가, RubyOnRails로 간다든가 해서, 설치 방법을 단순화할 수 있는 방법을 찾아보아야할 것 같습니다.

릴리즈를 위해서 데모 사이트도 만들었습니다. 관심 있으신 분은 둘러보시길.

한가지 덧붙일 것은, 0.1.0 릴리즈와 동시에, 갤럭시 개발 Iteration 3를 마치고, Iteration 4가 시작된다는 것입니다. Iteration 4에서 개발할 것들을 결정해서 곧 올리도록 하겠습니다.

Galaxy 0.1.0 Released! 더 읽기"

War Room과 Peopleware

다음은 likejazz.COM에 올라온 War Room에 관한 글에 대해 적은 comment. “DeMarco는 Peopleware에서 독립된 개발환경을 주장하지만, XP 또한 옹호하고 있는데, XP의 War Room과 배치되지 않느냐라는 생각”에 대한 반론이다. 여기서 김창준님의 comment도 참고.

이 comment를 적을 당시에는 마침 Peopleware의 그 부분을 읽는 중이었는데, comment를 쓰고 나서 읽은 그 다음 단락에서, comment에서 내가 얘기한 것과 똑같은 논지의 얘기가 나왔다. 즉, 팀은 대체로 같은 일을 하기 때문에, noise나 interruption에 의한 문제가 별로 없다는 것이다.

War Room과 Peopleware 더 읽기"

MT에서의 트랙백 인코딩 문제

대부분의 블로그 서비스가 트랙백 표준을 지키지 않고, EUC-KR 트랙백에 의존하고 있어서 MT로 트랙백을 보내는 데에 애로사항이 있다. 물론, Gratia님의 트랙백 패치도 있지만, 패치 자체가 복잡해서 귀찮은 나머지, 그냥 euc-kr로 보내도록 수정해버렸다. charset을 적절히 설정해주는 한 트랙백 표준 1.2에 위배되는 것은 아니니까… 그리고, UTF-8을 지원하는 블로그 구현이라면, 트랙백 표준도 제대로 구현하고 있을거야, 라는 약간은 안일한 가정. 다음 코드는 MT/lib/MT.pm의 수정사항.

의도한 것은 아닌데, 어쩌다보니 마루타가 되어버린, 젊은 거장님윗치님, 그리고 묵형에게 심심한 사과의 말씀을 드려야겠다. (사실 묵형쪽은 의도적으로 테스트한 것이다!)

        ## Build query string to be sent on each ping.
my @qs;
# BEGIN trackback patch by Joseph Jang
#push @qs, 'title=' . MT::Util::encode_url($entry->title);
#push @qs, 'url=' . MT::Util::encode_url($entry->permalink);
#push @qs, 'excerpt=' . MT::Util::encode_url($entry->get_excerpt);
#push @qs, 'blog_name=' . MT::Util::encode_url($blog->name);
use Encode;
push @qs, 'title=' . MT::Util::encode_url(Encode::encode("euc-kr", Encode::decode("utf-8", $entry->title)));
push @qs, 'url=' . MT::Util::encode_url(Encode::encode("euc-kr", Encode::decode("utf-8", $entry->permalink)));
push @qs, 'excerpt=' . MT::Util::encode_url(Encode::encode("euc-kr", Encode::decode("utf-8", $entry->get_excerpt)));
push @qs, 'blog_name=' . MT::Util::encode_url(Encode::encode("euc-kr", Encode::decode("utf-8", $blog->name)));
#END
my $qs = join '&', @qs;
#$qs = Encode::encode("euc-kr", Encode::decode("utf-8", $qs));
## Character encoding--best guess. Default to iso-8859-1, just as we
## do in MT::Template::Context::_hdlr_publish_charset.
# BEGIN trackback patch by Joseph Jang
#my $enc = $mt->{cfg}->PublishCharset || 'iso-8859-1';
my $enc = "euc-kr";
#END

MT에서의 트랙백 인코딩 문제 더 읽기"