2009년 06월 01일
무료문자발송 프로그램 MurMur v0.3

맥용 프로그램인데, 네이트온 무료문자창의 무료 및 문자쿠폰 건수까지 사용해서 발송 가능합니다.
네이트 캐쉬도 사용가능하도록 기능 추가하는 것 어렵지 않아 보이는군요.
맥이라서 그런지 디자인 마음에 드네요.
이런 서드파티 프로그램들은 막아야할지 말아야할지 고민중입니다.
# by | 2009/06/01 10:31 | 네이트온 | 트랙백 | 덧글(1)

# by | 2009/06/01 10:31 | 네이트온 | 트랙백 | 덧글(1)
웹서핑 중에 괜찮은 것들 미투데이에 스크랩하는데, 미투북마클릿이 편리하더군요.
그런데 미투북마클릿이 새창/새탭으로 뜨면 편리하겠다는 생각이 들어, 조금 수정해보았습니다.
미투북마클릿과 동일한 방식으로, 북마크하시면 됩니다.
javascript:(function(){var%20d=document;var%20w=window;var%20me=function(el){var%20o=d.createElement(el);if%20(typeof%20o!='object'){o=d.standardCreateElement(el);}return%20o;};var%20gst=function(){var%20t%20=%20'';if%20(w.getSelection){t%20=%20w.getSelection();}else%20if%20(d.getSelection)%20{t%20=%20d.getSelection();}else%20if%20(d.selection){t%20=%20d.selection.createRange().text;}return%20t;};var%20title=d.title;if(gst()!='')title=gst();var%20me='\"'+title+'\":'+location.href;w.open('http://me2day.net/posts/new?new_post[body]='+encodeURIComponent(me));})()
# by | 2009/04/07 10:52 | 프로그래밍 | 트랙백(2) | 덧글(2)
웹표준에 대한 다분히 감정적인 논란이 진행되는 것을 보고, 댓글을 달려다가 너무 길어지길래 트랙백하기로 하였습니다. 원문: http://noneway.tistory.com/429
논란은 간단합니다. 작성자가 크로스브라우징을 지키지 않는 한국 사이트들을 비판하는 포스팅을 올렸고, 그에 대해 몇몇 개발자가 "현실을 모르는 탁상공론"이라는 논지의 댓글을 단 것입니다. 원포스트 작성자가 그들을 犬발자라며 다시 포스팅한 것이구요.(이 블로그 전체적인 문체가 예의를 지키며 부드럽게 쓰는 방식이 아니니, 犬발자, 단세포들, 등신짓, 궤변 등등의 단어에 괜히 집착하지 말기를 바랍니다.)
'실천가'님의 댓글에 보면 "포털 메인 화면 같은 거 딱 한 페이지만 코딩해봐라"라는 말이 있던데, 제 경우엔 포털메인은 아니더라도 주요 서비스 중 하나를 전부 개발/운영 중이니 말할만한 자격을 충분히 갖춘 거죠? 웹to폰 SMS의 90%이상은 저희 시스템 통해서 나가지 않을까 합니다. 기획의도자체가 PC Applications 만큼의 기능성이라서 javascript를 얼마나 사용했을지 상상이 가시죠? 따라서 '지나가다', '실천가', '병신' 님의 "현실을 모른다"는 비난은 좀 무리가 있습니다. 메인페이지 개발자를 포함한 저희 회사 개발자들은 그일을 벌써 수 년간 해오고 있으니까요. 웹표준/크로스브라우징을 구현하는 것은 충분한 시스템이 갖춰져 있다면 분명히 "현실적으로도 가능"한 일입니다.
앞 문단과 모순되는 듯 보이지만, 그럼에도 불구하고 저에겐 犬발자라고 불리는 분들의 댓글이 단순한 궤변이나 변명으로 느껴지지는 않습니다. 현실적으로 어려움이 많고, 때로는 그 해결이 개발자의 영역 밖에 있는 경우도 있으니까요. "원칙적"으로 모든 사이트를 웹표준에 맞추고 크로스브라우징 가능하도록 개발하는 것이 가능하느냐라는 질문을 받는다면, 저는 "불가능하다"라고 대답하겠습니다
게다가 웹표준과 크로스브라우징은 전혀 별개의 개념입니다. 웹표준에만 맞게 작성한다고 모든 브라우저에서 잘 동작한다고 보장할 수 없고, 그 반대의 경우도 존재합니다. 만일 웹표준/크로스브라우징을 "웹표준에 맞게만 작성하면 크로스브라우징은 자동으로 보증된다"라고 이해하고 있다면 이것은 명백히 틀린 것입니다. (자세한 내용은 제일 아래부분 '덧붙여'에 설명해두었습니다)
웹표준은 말그대로 최소한의 표준일뿐이고, 표준화되지 않은 부분들에 대해서는 브라우저별로 알아서 구현되습니다. 이것은 웹표준 뿐 아니라 모든 기술스펙에 보편적인 사항인데, 웹표준스펙의 경우에는 특히 표준화가 더 불충분한 느낌입니다. 게다가 아직 working draft 상태죠?
게다가 웹표준과 크로스브라우징을 동시에 이루는 것은 불가능합니다. 모든 브라우저에서 동일하게 동작하기 위해 HTML 페이지의 웹표준을 희생하는 경우도 많이 있습니다. 예컨대, javascript 의 event 부분은 브라우저별로 차이가 큽니다. 이벤트 처리 코드들에서는 브라우저별로 분기하어 별도로 코딩하는 것이 필수적입니다. 내가 작성하는 코드가 다른 브라우저에서 동작할지 안할지는 해당 브라우저를 모두 테스트하기 전에는 전혀 알 수 없는 일입니다. 표준화가 잘 진행된 DOM 객체들 경우에도 모든 브라우저에서 동일하지 않은 예는 저 또한 많이 겪었습니다. 또는, 성능향상을 위해 javascript를 body 안에 넣는 비표준적인 일은 외국사이트들을 포함한 거의 모든 포털페이지들에서 자행(?)하고 있는 일일겁니다. 이것은 웹표준에는 맞지않지만 크로스브라우징이긴 하죠.
크로스브라우징/웹표준을 고려한 개발은 개발자 혼자 마음먹는다고 가능한 부분이 아닙니다. 기획팀에서 작성한 UI 를 구현하려면 어쩔 수 없이 웹표준을 어기게 되는 경우가 있습니다. 일례로 저는 이번 개편때에도 iframe 을 제거하지 못했네요.
표준을 지키려면 기획팀/디자인팀 등과도 그 내용이 공유되어야하는데, 웹표준/크로스브라우징 자체가 기술적인 내용이라서 이들을 교육시키는 것은 개발자 교육보다 더 어렵습니다. 어느 정도 시스템이 갖춰져있다는 저희도 아직은 개발중에 기획서 수정을 요청하는 경우가 많이 있고, 일부 기능을 위해서는 표준을 희생하기도 합니다. 사정이 이러니 웹표준을 어기고 크로스브라우징이 안되는 사이트 개발자를 무턱대고 犬발자라고 부르며 비난하는 것은 좀 억울합니다. 우리 기획팀/디자인팀과 일정을 재촉하는 경영진을 함께 비난하시던지 ^^;
개발영역에서만 보더라도 기존 코딩방식에 익숙한 개발자가 웹표준을 익히고 크로스브라우징을 고려하는 일이 말만큼 쉽지는 않습니다. 저희회사는 HTML코딩을 담당하는 팀에서 자바스크립트 코딩까지 99% 완료한 상태로 전달해줍니다. 저는 JSP 코드만 추가하는데, CSS관련 문제는 해당 팀에 문의하여 즉각적으로 답변 및 수정사항을 전달받습니다. 이렇게 일하면서도 처음 웹표준을 익히는데 몇 달은 걸리더군요. 전담팀의 도움 없이 웹표준을 익힌다는 것은 상상이 안갑니다.
게다가 단순히 크로스브라우징도 아니고 웹표준에 맞춘다는 것은 HTML에 대한 컨셉을 바꾸는 것이기 때문에 더욱 어려운 일입니다. 웹표준 관련 제대로된 책은 있나요? 웹표준 관련해서 찾아보고 물어볼 수 있는 블로그나 커뮤니티는 얼마나 될까요? 제게는 마치 윈도우만 써보던 개발자에게 "이제부터 PC포맷하고 리눅스깔아서 써라"라는 말정도로 들리네요.(책도 없이, man페이지 있으니 알아서 써라 정도?) 기존처럼 테이블들로 대충대충 꾸미다가, 구문맞춰서 HTML코딩하고 CSS로 모양 바꾸고 그러는 작업은, HTML에 대한 컨셉을 바꾸는 것이기 때문에 전혀 간단하지가 않습니다.
웹표준이라는게 영세한 Web Agency들의 능력으로는 개발자교육조차 어려워보입니다. 교육시켜줄 인력조차 없을테니까요. 그정도 훌륭한 코더라면 이미 큰회사에 스카웃되었을껄요. 사회적인 지원이 전무한 상황에서 '게으른 犬발자'라고만 비난하는 것은 지나칩니다. 저희처럼 전사적으로 웹표준관련 공유와 지원이 잘 되어있는 회사에서도 아직 한숨만 나오게 하는 개발자분들 많습니다. 하물며 영세업체들은 ㅡㅡ.
K리그에는 관심도 없으면서 한국축구가 월드컵 우승 못한다고 선수들의 정신력을 비난할 수는 없습니다. 제 생각에 웹표준/크로스브라우징은 IT업계전체의 의지가 필요한 이슈입니다. 그러나 30억으로 닌텐도DS를 만들어야하는 한국 사회는 당연히 그렇지 못합니다. 올봄부터인가 웹접근성관련 법안이 발효되어 표준을 제대로 지키지 못한 사이트를 소비자가 소송하는 것이 가능하다던데, 언제나처럼 위에 계신 분들은 막상 업체를 어떻게 지원할지에 대해서는 고민을 안하시고 계신 듯 하네요.
웹표준/크로스브라우징이 전혀 다른 개념이고 서로 직접적인 관련이 없습니다.
사실 웹표준은 정확한 스펙 내용보다도 표준을 지정할때 지향하는 방향성이 더 중요할 것 같습니다. HTML의 내용과 Tag 가 적절한 의미를 가지고 조합되는 것이 그것인데, symantic 이라고 해야할까요? CSS가 로딩되지 않았을때 www.nate.com의 HTML 페이지를 보신적 있으신가요? HTML은 의미를 가진 Document 가 되고, 그것을 화면에 보여주는 것은 CSS가 담당하도록 작성하는 것이 웹표준의 핵심이 아닐까 합니다. 이렇게 되면, CSS에 정의된 대로 제대로 표시하지 못하는 브라우저들의 경우에도 HTML 페이지를 읽는 것이 가능하게 되겠죠.
다른 브라우저 읽힌다라는 속성때문에 웹표준을 크로스브라우징과 많이들 혼동을 하지만,실제로 크로스브라우징은 전혀 다른 의미입니다. 앞서 말한 것처럼 어떤 브라우저에서 레이아웃이 다르게 보인다면, 일반적으로는 크로스브라우징이 안된다고 말을 합니다. 크로스브라우징은 모든 브라우저에서 완전히 동일하게 표시/작동될 때를 의미합니다. 반대로 iframe 같은 것은 크로스브라우징이지만 웹표준에는 어긋납니다.
꿈틀꿈틀님의 포스팅 몇 개를 보았는데, '웹평등'을 말하실때 웹표준이라고 말하면서 크로스브라우징을 의미하는게 아닌게 싶습니다. 가령 네이트/네이버사이트에서 광고배너나 검색창이 제 위치에 안보이는 것 자체가 웹표준을 어겼다고 말하는 것은 틀린 말입니다. 물론 웹평등/웹접근성에서 웹표준은 필수적인 개념이라는 것이 옳은 말이고, 관련 글들의 행간을 읽는다면 웹표준->웹평등성 으로 연결되는 사고의 흐름을 읽지 못할 바는 아닙니다. 하지만 글 자체에서 쓰일 때에는 웹표준과 크로스브라우징이 혼동되고 있는 것으로 보이네요. 웹페이지 작성시 symantic 을 지키라는 것인지, IE이외의 브라우저에서도 잘 돌아가도록 만들라는 것인지, 논지를 명확히 해주시면 더 읽기 좋을 것 같습니다.
# by | 2009/03/23 12:00 | 프로그래밍 | 트랙백(3) | 덧글(25)

# by | 2009/02/27 16:58 | 네이트온 | 트랙백 | 덧글(2)

# by | 2009/02/27 16:56 | 네이트온 | 트랙백 | 덧글(0)
Strategy 패턴을 연습해보려고 직접 코드를 작성했습니다. 가위바위보 게임인데, 손을 내미는 전략을 Strategy 패턴을 사용해서 구현했습니다.
랜덤하게, 또는 순서대로 등등 전략에 따라 어떤 전략이 가장 승률이 높은지 계산해보기 위해 만들었습니다.
이 예제는 영진출판사의 "Design Pattern 입문"이라는 책의 예제를 모티브로 하여 만들었습니다.
소스는 http://realmoveprivatespace.googlecode.com/svn/trunk/designpattern/src/com/egloos/realmove/dp/strategy/ 에서 보실 수 있습니다. 동일한 경로에서 svn 다운로드도 가능합니다.
먼저,
com.egloos.realmove.dp.strategy.framework 패키지 아래의 세 파일이 기본이됩니다.
다음,
com.egloos.realmove.dp.strategy 패키지에 HandGameStrategy 를 구현하는 4가지 클래스가 있습니다.
그리고, 테스트용 main 함수들입니다.
아래는, Main2.java 실행결과입니다. 각각 3만번씩 실행하였으므로, 승률이 10000 보다 높으면 훌륭한 알고리즘이겠죠. 얼핏 보니, ProbStrategy의 승률이 들쑥날쑥하고, 대부분의 승률이 비슷합니다. 이렇게 승률이 비슷하다니 가위바위보가 상당히 우수한 게임이군요.
Pororo using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 0 loose: 0 draw: 30000
Thomas using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 0 loose: 0 draw: 30000
-----------------
Pororo using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 10113 loose: 9729 draw: 10158
Thomas using com.egloos.realmove.dp.strategy.RandomStrategy
win: 9729 loose: 10113 draw: 10158
-----------------
Pororo using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 10002 loose: 9999 draw: 9999
Thomas using com.egloos.realmove.dp.strategy.WinningStrategy
win: 9999 loose: 10002 draw: 9999
-----------------
Pororo using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 10058 loose: 9981 draw: 9961
Thomas using com.egloos.realmove.dp.strategy.ProbStrategy
win: 9981 loose: 10058 draw: 9961
-----------------
Pororo using com.egloos.realmove.dp.strategy.RandomStrategy
win: 10081 loose: 10016 draw: 9903
Thomas using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 10016 loose: 10081 draw: 9903
-----------------
Pororo using com.egloos.realmove.dp.strategy.RandomStrategy
win: 9993 loose: 9878 draw: 10129
Thomas using com.egloos.realmove.dp.strategy.RandomStrategy
win: 9878 loose: 9993 draw: 10129
-----------------
Pororo using com.egloos.realmove.dp.strategy.RandomStrategy
win: 10046 loose: 10043 draw: 9911
Thomas using com.egloos.realmove.dp.strategy.WinningStrategy
win: 10043 loose: 10046 draw: 9911
-----------------
Pororo using com.egloos.realmove.dp.strategy.RandomStrategy
win: 10041 loose: 9900 draw: 10059
Thomas using com.egloos.realmove.dp.strategy.ProbStrategy
win: 9900 loose: 10041 draw: 10059
-----------------
Pororo using com.egloos.realmove.dp.strategy.WinningStrategy
win: 10000 loose: 10000 draw: 10000
Thomas using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 10000 loose: 10000 draw: 10000
-----------------
Pororo using com.egloos.realmove.dp.strategy.WinningStrategy
win: 9955 loose: 9929 draw: 10116
Thomas using com.egloos.realmove.dp.strategy.RandomStrategy
win: 9929 loose: 9955 draw: 10116
-----------------
Pororo using com.egloos.realmove.dp.strategy.WinningStrategy
win: 29996 loose: 2 draw: 2
Thomas using com.egloos.realmove.dp.strategy.WinningStrategy
win: 2 loose: 29996 draw: 2
-----------------
Pororo using com.egloos.realmove.dp.strategy.WinningStrategy
win: 15456 loose: 2152 draw: 12392
Thomas using com.egloos.realmove.dp.strategy.ProbStrategy
win: 2152 loose: 15456 draw: 12392
-----------------
Pororo using com.egloos.realmove.dp.strategy.ProbStrategy
win: 10062 loose: 9964 draw: 9974
Thomas using com.egloos.realmove.dp.strategy.SequenceStrategy
win: 9964 loose: 10062 draw: 9974
-----------------
Pororo using com.egloos.realmove.dp.strategy.ProbStrategy
win: 10001 loose: 10005 draw: 9994
Thomas using com.egloos.realmove.dp.strategy.RandomStrategy
win: 10005 loose: 10001 draw: 9994
-----------------
Pororo using com.egloos.realmove.dp.strategy.ProbStrategy
win: 7521 loose: 9853 draw: 12626
Thomas using com.egloos.realmove.dp.strategy.WinningStrategy
win: 9853 loose: 7521 draw: 12626
-----------------
Pororo using com.egloos.realmove.dp.strategy.ProbStrategy
win: 9022 loose: 15115 draw: 5863
Thomas using com.egloos.realmove.dp.strategy.ProbStrategy
win: 15115 loose: 9022 draw: 5863
-----------------
# by | 2009/01/16 15:29 | 프로그래밍 | 트랙백 | 덧글(0)
명령을 캡슐화 한다. cf. Strategy, State, Factory 패턴에서는 각각 알고리즘, 상태, 생성을 캡슐화 한다.
사용법이 Interpreter 패턴과 유사하기도 하다.
# by | 2009/01/12 15:42 | 프로그래밍 | 트랙백 | 덧글(0)
strategy(전략) = algorithm 을 교체한다.
Context using strategy.
strategy is Interface as abstractStrategy.
concreteStrategies implements strategy.
# by | 2009/01/12 14:37 | 프로그래밍 | 트랙백 | 덧글(0)

이런 형태의 주소록 데이터를 여러 가지 형식으로 출력할 수 있도록 코드를 작성하려고 합니다. 출력 형식은 계속해서 추가될 수 있으니 확장성을 고려하여 Abstract Pattern으로 작성하도록 하였습니다.
제가 작성한 출력 형식들은 오른쪽 이미지와 같습니다. 클릭하여 크게 확대할 수 있습니다.
Abstract Pattern이 무엇인지는 웹검색을 통해 쉽게 찾을 수 있으니 다시 설명하지 않겠습니다. 다만, Abstract Factory와 Abstract Product들이 있고, 실제로 그것들을 구현한 Concrete Factory와 Concrete Product 들이 있다는 것만 언급하겠습니다.
소스는 아래 3가지 방법 중 하나를 사용하여 구할 수 있습니다. JDK1.5 이상에서 컴파일 및 실행하세요.
파랗게 선택표시된 클래스들을 먼저 보시기 바랍니다. 중간쯤에 4개의 클래스를 가진 framework 패키지가 있습니다. 패키지 이름 그대로 기본 프레임워크 역할을 하는 패키지로서 4개의 추상 클래스들을 가지고 있습니다.
최대한 유연한 확장성을 생각한다면 4개의 클래스 모두를 interface 로 만들어주는 것이 좋겠으나, 구현의 편의상 abstract class 로 작성하였습니다. 사실은 각각 interface 로 만들고, 편의성을 위해서는 그것을 implement한 abstract class 를 별도로 만드는 것이 바람직했겠죠. 하지만 그렇게 하면 코드 구조가 복잡해져서^^;;
Tester 클래스는 Client역할의 클래스로서, main()메소드를 가지고 있고 그 안에서 각각의 클래스들을 생성하여 실행하게 됩니다. Factory 를 먼저 생성한 다음, 각각의 Product 들을 생성하는 방식으로 구동됩니다.
소스코드에서 확인하시다시피 Factory 를 생성할 때를 제외하면 framework 패키지의 abstract 클래스들만을 사용하고 있습니다. 즉 Client는 구체적인 구현내용은 알 필요 없도록 하는 것이 확장성을 최우선으로 하는 이런 류의 패턴들의 핵심이겠죠.
Factory 생성부분도 생성자를 직접호출하지 않고, Class.newInstance()를 사용하여 생성하였습니다. 클래스명을 스트링으로도 받아서 생성할 수도 있을 정도이니, 구체적인 Factory와는 극도로 느슨하게 결합되어 있다고 할 수 있을 것입니다.
csv 패키지를 보시면 framework 패키지 클래스들이 똑같다는 것을 확인할 수 있습니다. Abstract 대신 Csv 가 사용된 것 뿐이죠. framework 들의 AbstractProduct 들이 output() 메소드를 구현하지 않고 추상메소드로 남겨두었으니, 이 ConcreteProduct 들에서는 output() 메소드를 구현해주면 되겠죠. ',' 와 '\n'으로 적당히 구분하여 내용들을 출력해주면 됩니다.
ConcreteFactory인 CsvAddressBookFactory의 구현은 더욱 간단해서 부연 설명이 필요 없겠네요.
XML 형태로 출력하는 클래스들을 만들어보면 어떨까요? 마찬가지로 framework 에 있는 클래스들을 거의 그대로 extends 해서 output() 메소드와 createXXX() 메소드들을 구현해주면 됩니다.
앞으로 나올 wiki 형식, html 형식으로 출력하는 클래스들도 전혀 다를 바가 없습니다.
이런 것이 바로 패턴과 framework 을 사용할때의 이점이겠죠. 규칙만 미리 알고 있으면 기능을 추가하는 일은 단순하고 기계적인 일이 됩니다. 코딩도 쉽고, 결과적으로 버그가 발생할 가능성도 그만큼 줄어듭니다. Eclipse 같이 Refactoring 기능이 잘 구현된 IDE를 사용한다면 훨씬 더 작업이 간단해질 것입니다. 제가 작업할때 약 2분 정도씩 걸리더군요.
Text 형식으로 출력해보죠. CSV 형식으로 출력하는 것과 동일한데, 이번엔 그룹명을 중간에 넣어볼까 합니다.그러러면 Address가 자신의 Group 정보까지 알고 있어야 할테니까 다른 출력양식을 추가할 때 했던 것 이외에 조금 더 수정이 필요할 것입니다.
Abstract Pattern 을 사용하여 일종의 framework 를 구성해두면 이후에 기능을 추가하는 일이 아주 간단해지는 것을 확인할 수 있었습니다. 이 패턴을 포함한 몇몇 패턴들이 가진 큰 장점일 것입니다.
이 패턴이 흥미롭다고 느껴지면, 출력형식들을 계속해서 추가하는 일들을 할 수 있을 것입니다. 예컨대, 이 예제에서는 HTML 형식을 사용할 때 UL, Table 태그만 사용했지만, dt, ol 등 다른 태그로 구현할 수 있고, 모양도 다르게 출력할 수 있겠죠.
또한 이 패턴과 직접 관련은 없으나 Client 를 개선해가는 것도 재미있을 겁니다.
주소록 데이터를 파일이나 네트워크에서 얻어오도록 할 수도 있을 것입니다. 데이터를 애초에 XML형식으로 저장하고 XML 파서 내부에서 Product 들을 생성하게 하는 것도 재미있겠죠.
swing, awt, swt 등의 GUI 에 익숙해져 있다면, 좌측에 데이터, 우측에 출력창을 두고 데이터를 마음대로 변환할 수 있고, 출력형식을 선택하여 동적으로 출력이 이루어지도록 작업하는 것도 어렵지 않을 것입니다. 데이터가 변경될 때 출력에도 바로 반영되도록 하려면, Observer 패턴을 적용하면 더욱 좋겠네요.
제 경우엔 output() 메소드가 String이 아닌 OutputStream 을 반환하도록 설계하지 않은 것이 아쉽군요. 속도나 부하 등을 고려한다면 OutputStream으로 출력하는 것이 튜닝하기 훨씬 유리한 데다가, 출력시 인코딩을 다양하게 하려면 Stream이나 byte[]로 출력하는 것이 필수적일 테니까요.
현재 코드를 이렇게 고치려면 먼저 Stream 을 반환하는 getOutputStream() 메소드를 가진 AbstractProduct들을 만들어두고, 그것을 extends 한 ConcreteProduct를 하나하나 만들어가면 되겠죠. 혹시라도 String 반환하는 기존 시스템에서도 이용하고자 한다면, 양자를 이어줄 수 있도록 Adapter 패턴을 적용하는 건 어떨까 합니다.
# by | 2008/12/29 00:40 | 프로그래밍 | 트랙백 | 덧글(0)


# by | 2008/10/21 10:37 | 네이트온 | 트랙백 | 덧글(0)