달력

6

« 2025/6 »

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
오늘은 집에 아무도 없는 관계로 이것 저걱 시도해 보았다.
결과 적으로는 아무것도 한것이 없는 것이 되어 버렸지만, 많은 것을 하려 했던 시도자체의 문제라기 보다는 집중하지 못하는 것이 문제 였다.

하루중에서 가장 기억나는 것은 오전에 케이블 방송에서 해주었던 어떤 프로그램에 대한 것이었다.
별로 TV를 즐기거나, 좋아하지 않는다. 물론 한번 빠지면, 이것 저것 제쳐놓고 꼭 보고야 마는 집요한 성격을 가지고 있지만, 회사가 집과 먼 관계로 집중해서 보는 프로그램은 없다. 
그런데, 집에 들어오면 꼭 TV를 틀어놓고 다른 일을 하거나, 책을 보곤한다. 아니면, 오늘 처럼 노트북을 펼쳐놓고 다른 작업을 하면서, TV에서 나오는 소리를 마치 라디오 방송을 듣는 것처럼 듣곤한다. 이 경우 대부분 뉴스를 하는 방송에 채널을 고정해 놓는다. 요즘은 24시간 뉴스만 틀어주는 방송이 있으니까, 시간마다 기다릴 필료도 없다.

TV채널을 틀다가, 한 방송에 나의 시선이 고정되었다. 늦은 오전 이었지만 아직 식사 전이어서인지, 시장했던 나는 맛있어 보이는 스테이크를 보여주는 화면에 푹 빠져버렸다. 정말 맛있어 보이는 큼직한 스테이크 였다. 방금 구워서인지 화면 속에서 보이는 김이, 나의 코와 입속의 침샘을 자극해 버렸다.

채널이 고정되고, 정신을 차리고 어떤 프로그램인지 살펴 보았다. "미션! 최고의 레스토랑2"라는 제목으로 미국에서 제작된 방송이는데, 망하기 일보직전인 레스토랑을 살리는 프로그램이었다.
중간을 지나서 방송을 보기 시작해서, 중간에 어떤 사연들이 있었고, 어떠한 준비를 하였는지는 모르겠지만, 새롭게 개장한 레스트랑은 새로은 음식과 소스를 가지고 손님들을 맞이하고 있었다.

주방에서는 이 프로그램의 주인공(?)격인 주방장의 지시에 따라 음식이 만들어 지고 있었다.
새로 만들어진 음식과 소스는 이전과는 달리 맛있고 차별화된 메뉴였기 때문에 손님들에게 인기가 있을거라 모두들 기대하고 있었고, 실제로 손님에게 음식이 나오자 손님들의 반응이 좋았다.

여기서, 모든 이야기가 끝이라고 생각했는데, 그것이 아니었다. 주방에서는 주방장의 지시로 만들어지는 음식들이 하나 하나 체크되어지고, 식당으로 나갈 음식의 그릇조차 지져분해 보이면, 가차없이 경고가 이어졌다. 저녁시간에 되어, 레스토랑에 손님들이 점점 늘어나는 상황에서, 제한된 인원과 리소스를 가진 주방에서는 마음만큼 음식들이 만들어 지지 못하는 상황이었고, 급한 마음과 달리 실수가 많아지기 시작하였다.
그러한 상황에서도 메일 주방장은 결코 음식의 질에 대해서 양보하지 않았고, 더욱더 음식에 대한 요구가 많아지기 시작하였다. 
이러한 상황에서, 1시간이 넘도록 기다리는 손님들이 생겨나기 시작하였고, 결국 사장과 지배인을 불러서 불만을 이야기 하는 상황이 되었다. 사장은 당황하였고, 어찌할 바를 몰랐다. 조금만 더 기다리게 하면 손님들이 그냥 돌아가는 사태가 일어날 것이기 때문이었는데, 어떻게 기다리라고만 할 수 있겠는가?

결국, 주방으로 들어가서, 주방장에게 강력하게 음식을 빨리 만들어 줄것을 요청한다. 그러나 주방장의 태도는 별화가 없었다. 음식이 나오지만, 질적으로 떨어지거나, 제대로 만들어지지 않은 음식은 가차없이 다시 만들도록 한다. 그리고 제대로 만들어져 나온 음식일 지라도, 먹음직스럽게 셋팅되지 않거나, 소스가 티어서 지저분해 보이면, 이역시 제대로 잘 정리되지 않으면 내 보내지 않았다.

사장과 지배인은 이러한 상황에서, 주방장이 레스토랑으로 내보내려 하지 않던 음식을 직적 가지고 나가려고 하는데, 이때 주방장은 강력하게 제재를 가한다. 
이 순간을 타협해서는 안된다고, 음식의 질을 떨어뜨리면 결코 안된다고, 손님이 아무리 뭐라고 하더라도 음식의 질만을 유지해야하고 맛있는 음식을 손님에게 제공해야 한다고 강력하게 이야기 한다.
사장과 지배인 그리고 주방에서 일하는 다른 사람들은, 마침내 이 말에 동의하기 시작하고, 바쁘고 힘든 상황에서 서로와 서로를 격려하기 시작한다.

이때, 1시간 이상을 기다리던 손님은 욕과 함께 식당을 떠난다. 
주방에서는 공통된 목표가 있기 때문인지, 아니면 주방장의 격려의 목소리 때문인지 아까보다도 더 활기차게 음식을 만들고 있었다. 이 들이 만든 음식을 먹던 손님들은 모두가 만족스러워 한다. 
마침내 마지막 손님이 돌아가고, 남은 이들은 모여서 자신들이 이루어 낸 하루를 무척 만족스러워 하게된다. 
"다른 어떤 것보다도 음식의 질은 떨어뜨리지 말자. 손님에게 양질의 음식을 만들어 주어야 한다." 라는 주방장의 말을 끝으로 전쟁과도 같은 하루가 마쳐진다.
몇 달후, 이 레스토랑은 그 지역의 최고의 레스토랑으로 선정되고, 몇개의 상을 타게 된다. 

이 프로그램의 보면서, 내가 느꼈던 것은 개발자와 개발을 하는 회사는 과연 무엇을 위해서 타엽을 할까? 라는 생각이 들었다. 1시간 이상 기다리던 손님에게, 양질의 음식대신, 그렇지 못한 음식을 먹게하고, 별다른 만족을 주지 못한다면, 이 손님은 결코 다시 돌아오지 않을 것이다.
물론, 2시간씩 기다리게 하는 식당도 다시 가고 싶지는 않을 것이다. 하지만, 그렇게 기다릴 만큼 맛있는 음식이라면, 몇명은 다시 올지도 모르겠지만...

최근에 외근을 나간적이 있는데, 현장에서는 신 제품에 대한 품질에 대한 불만들이 많았다. 제품의 출시 일정을 맞추는 것은 상당히 중요할 일이기는 하지만, 그러나, 출시 일정때문에, 기준이하의 품질의 제품을 만든다면, 당장의 매출은 올릴수 있을지 모르지만, 그 다음은 확신할 수 없을 것이다.
당장의 이익과 장기적인 이익의 차이는 얼마나 큰 차이인지는 정확히는 모르지만, 개발자로서는 품질에 대한 고집을 가져가야 한다고 생각한다. 물론 이는 개발자의 몫일 뿐만 아니라 개발사의 몫이기도 하다.
한국의 개발현실은 그렇게 녹녹치 않다는 것도 이미 잘 알고 있다. 그러나, 정말 내가 타협하지 말아야 할 부분이 무엇인지를 생각할 수 밖에 없었다.

중소 IT업체의 CEO분을 만나서 들은 이야기 중에, 황당한 내용이어서 기억하고 있는 것이 있다. 어떤 프로젝트에서 말도 안되는 일정때문에, 일정을 맞추기 위해서 프리렌서를 모집해서, 고생끝에 개발을 완료하였는데, 이 프로젝트를 마침과 동시에 프리랜서들은 핸드폰 번호도 바꾸고 잠적해 버렸다는 것이다.
왜 잠적하였을까? 여러가지 이유가 있었겠지만, 결국 모두 망하는 길이 될 것임은 불 보듯 뻔하다.

회사에서 만들어 내는 제품도 마찮가지이다. 한 제푸의 신뢰가 또 다른 제품의 신뢰로 이어질텐데, 제대로 되지 않은 품질의 소프트웨어와 하드웨어를 고객에게 제공하고 이를 A/S를 통해서 품질을 보완한다는 것은 고객에게 책임의 일부를 전가하는 것과 같은 일이다. 
한가지 알아야 할 일은, 인터넷 시대의 고객을 무척 똑똑하다는 것이고, 그 입이 무척 크다는 것이다.

좋은 제품은 품질이 바탕이 되어야 하고, 개발자는 앞서 이야기한 요리사와 같이 항상 머리속에 되세겨야 할 것이다. 항상 하는 이야기이지만, 개발자는 자기의 코드를 통해서 이야기 해야 한다. 그리고 아키텍트는 복잡한 것을 단순화 시키는 능력으로 말을 해야 할 것이다.

이렇게 되기 위해서는 끊임없이 배우고 익혀야 한다.
조그마한 재주를 가지고, 누구를 기쁘게 할 지는 모르지만, 자기 조차 먹일수 없는 음식을 남에게 내 놓을수는 없을 것이기 때문에, 모자라는 부분은 지속적으로 개선해야 할 거라 생각한다.

오늘은 짧고 간단한 이야기를 하고 싶없는데, 말이 길어졌다.

 

 






















:
Posted by 행복상자
오늘은 최근 며칠전에 보아 두었던, Twitter4J 의 API와 이를 Java에서 사용가능하도록 구현한 Twitter4J 를 분석하기로 마음 먹었다. 일단 웹에서 Twitte4J 2.0.8버전을 다운로드 받아서, Eclipse에서 환경을 만들어보았다. 다운로드 받은 파일을 압축을 풀면, Source Code와 Sample Code 그리고 Junit 코드가 있다.
Junit 코드는 Twitter4J 라이브러리의 사용법을 손쉽게 익힐수 있는 좋은 예제이다.

몇가지 테스트를 하다보니, 클라스의 메소드들의 내용을 출력해서 볼 필요가 있어서, 이를 Console에 찍어보았는데, 메소드 또는 getter를 통해서 Twitter 서버의 결과들을 가져와 그 내용을 살펴 볼수 있었다.

아래과 같이 Java Doc에 있는 문서를 뒤져서, System.out.println() 메소드를 이용하여 처음에 만들어 보았다.  
public void testSearch() throws TwitterException
 {
        Twitter tw = new Twitter();
        String queryStr = "happyzoo";
        Query query = new Query(queryStr);
        QueryResult queryResult = tw.search(query);
     
        List<Tweet> tweets = queryResult.getTweets();
        System.out.println("tweets.size: ==> " + tweets.size());
               
        for (Tweet tweet : tweets) {
         System.out.println("tweet.getText: ==> " + tweet.getText());
       System.out.println("tweet.getSource: ==> " + tweet.getSource());
                    ....    
        }
 }



위의 코드는 Junit을 이용하여 테스트용으로 만든 코드이지만, 코드의 내용을 검증하지는 않았다. 개인적으로는 TDD를 선호하지만, 갑작스럽게 확인하거나 할때는 그냥 junit에다 테스트 코드를 작성하고, 나중에 Refactoring을 한다. 새로운 Library를 익혀야 하거나 테스트 코드를 짜볼 때는 Junit로 테스트를 작성하고, 나주에 필요할 때, 다시 이를 보고, 사용법을 익히는 시간을 줄이곤 한다.

그리고, 사실 다음 단계들이 Refacoring을 하는 단계라고 생각할 수도 있다.
위의 코드가 그리 보기 않좋았다. 그래서 이를 다시 수정하였다. 나중에 코드를 작성할때 필요한 내용들을 확인할 때 재 사용이 가능할 거라고 생각하였다. (이 역시 나의 습관인데, 별도의 클래스의 작성 필요 없는 경우는 static으로 메소드를 선언하여 사용하곤 한다.)


private static void showTweet(Tweet tweet){
    StringBuffer showData = new StringBuffer();
    
    showData.append("tweet.getCreatedAt():" + tweet.getCreatedAt() + "\n");
    showData.append("tweet.getFromUser():" + tweet.getFromUser() + "\n");
    showData.append("tweet.getFromUserId():" + tweet.getFromUserId() + "\n");
    showData.append("tweet.getId():" + tweet.getId() + "\n");
    showData.append("tweet.getIsoLanguageCode():" + tweet.getIsoLanguageCode() + "\n");
    showData.append("tweet.getProfileImageUrl():" + tweet.getProfileImageUrl() + "\n");
    showData.append("tweet.getSource():" + tweet.getSource() + "\n");
    showData.append("tweet.getText():" + tweet.getText() + "\n");
    showData.append("tweet.getToUser():" + tweet.getToUser() + "\n");
    showData.append("tweet.getToUserId():" + tweet.getToUserId() + "\n");

  
    System.out.println("showData: " + showData);
 }

위 처럼 코드를 만들고 나서는, 다른 클래스에 대한 값들을 또한 확인해야 할 필요가 느껴졌다.
그런데, 위와 같은 "showData.append("... ")" 라고 일일이 쳐 주어야 하는 것이 비 생산적이라는 생각이 들어서, 자동으로 위와 같은 형태로 생성해 주면, 이를 출련한 후에 실제 코드에서 생성해서 붙여 쓰는 것이 더 생산적일 거라는 생각이 들어서, 코드를 만들어 주는 코드를 아래 처럼 짜써 넣었다.

public void createTempletCode()
 {
String[] methods = new String[]{
"getCreatedAt",
"getFromUser",
"getFromUserId",
"getId",
"getIsoLanguageCode",
"getProfileImageUrl",
"getSource",
"getText",
"getToUser",
"getToUserId"
  };
  
String str = "";
for (String method : methods) {
str += "showData.append(\"tweet." + buffer + "():\" + " + "tweet." + method + "() + \"\\n\");\n";
}
  
System.out.println(str);
 }

위의 코드는 실제 코드를 만들때의 노가다를 상단부분 없애 주었다. 물로 1~2를 위해서 쓴다면, 여기까지 만든 노력이 별로 효과가 없지만, 말이다. 하지만, 역시 단점이 있다, 메소드들을 java Doc을 뒤져서 복사해서 배열로 만들어 줘야 한다. 이 역시 적지 않은 노가다가 든다. Copy & Paste를 한다해도 메소드가 많다면, 이 역시 쉬운 작업을 아니다.

역시 한번더 개선을 해야 겠다. 일단 위의 코드를 아래처럼 별도이 메소드로 만들어 주었다.

 public static String createTempletCode(String[] methods, String instanceName)
 {
String temp = "";
for (String method : methods) {
   temp += "showData.append(\"" + instanceName + "." + method + "():\" + " + "tweet." + method + "() + \"\\n\");\n";
  }
   
  return temp ;
 }

그리고, reflection을 이용하기로 했다. 이는 junit과 AspetJ 또는 AOP에서 많이 사용되고 있고, 실제로 윈도우나 Java에서 최근들어 많이 사용되고 있는 방법이다. 그러나 사실 일반적인 개발시는 많이 이용하지 않고 있다. 그러나 나는 오는 나의 노가다를 쫑 내기 위해서, 이를 이용할 수 밖에 없었다.

"java.lang.reflect.Method"를 이용해서 내가 java Doc에서 가져오던 내용들을 한번에 가져오기로 하고 다음과 같이 수정하였다. 만약 제대로 가져오면, 위에 있는 메서드를 이용하여 쉽게 원하는 것을 출력할 수 있을 것이다.
 
public void createTempletCode()
 {
System.out.println(createTempletCode(getMethodOfClass(Tweet.class), "tweet")); 
 }

public static String createTempletCode(String[] methods, String instanceName)
 {
String temp = "";
for (String method : methods) {
 temp += "showData.append(\"" + instanceName + "." + method + "():\" + " + "tweet." + method + "() + \"\\n\");\n";
  }
   
  return temp ;
 }

public static String[] getMethodOfClass(Class clazz)
 {
  Class thisClass = clazz;
  Method[] methods = thisClass.getDeclaredMethods();
  
  String[] methodNames = new String[methods.length];
  
  for(int i =0; i < methods.length; i++ )
  {
methodNames[i] = methods[i].getName();
   
  }
  
  return methodNames;

}


코드가 많이 단순해 졌다. 처음 생각했던 내용들이 시간의 흐름사이에서, 생각도 변화하고 아이디어도 변화해서, 위와 같은 모습이 되었다.
조금 전까지도, 어차피 reflection을 적용했으니까, 생성한 코드를 바로 실행하는 로직을 만들어 넣을까도 생각했지만, 이거는 오버스펙이 될거라는 생각에 오늘은 더 이상 추가하지 않을 계획이다. 아직도 몇가지 코드들은 refectoring을 기다리고 있으니 말이다.

Twitter4J의 클래스와 메소드들은 생각보다 사용하기 쉽고, 단순하다.그리고, 이는 일본사람이 만들어서 인지 Unicode에 대한 문제도 없어 보인다.

오늘은 별다른 래퍼 클래스를 만들지 않고, 몇가지 테스트만 더하고, 내가 원하는 것을 한번 만들어 볼 생각이다.


'공부하는 것' 카테고리의 다른 글

GRails 공부 자료들...  (0) 2009.10.04
Silverlight 3 Released  (0) 2009.07.11
Free ASP.NET MVC “NerdDinner” Tutorial Now in HTML  (0) 2009.05.01
Free ASP.NET MVC eBook Tutorial  (0) 2009.03.12
Microsoft Azure Platform  (0) 2008.12.29
:
Posted by 행복상자
애플에 어제 올라온 비교 자료인데, 한국에서 출시되면 어떤것을 살것인가에 대한 고민은 너무나 쉽게 일축시키는 표이다. 물론 구매에 필요한 돈이 된다면야, 고민할 것은 아니지만 말이다.

한국에서의 iPhone의 출시는 이제 거의 기정사실화 되는 분위기이다. 아니 오히려 마케팅 적인 측면에서는 많은 도움이 될거라 생각한다.

내가 가지고 있는 iPod Touch는 iPhone에 비해서 기능이 부족하거나, 제거되어진 채로 출시되고 있다. 물론 나름 만족하고 있지만, 아쉬운점은 항상 있기 마련이다.


과연 어떠한 것을 고를 것인가?

자세한 자료는 http://support.apple.com/kb/HT3630 를 참조하면 된다.

'공부하는 것 > iPhone Application' 카테고리의 다른 글

iPhone Application Life Cycle  (0) 2009.06.01
iPhone SDK Study  (0) 2009.05.31
:
Posted by 행복상자
최근에 몇가지 새로운 프로그램과 디바이스들이 속속들이 발표되어 있다.
이를 기다리고 있는 사용자와 개발자들은 매우 반갑고도 기쁜 소식일 것이다. 이로 인해서 인터넷은 날마다 뜨겁게 달아오르고 있는 중인데, 재미 있는 것은 모두 다 비슷한 시기에 발표되고 있다는 것이다. 그리고 비슷한 전략들을 가지고 시장에 나오고 있는데, 모두다 내실있어 보이지는 않는다. 한편으로는 그 만큼 지키기가 힘들다는, 수성하기가 힘들다는 반증이기도 하다. 새로운 제품과 App Store를 서로 경쟁적으로 오픈하고 있으니 말이다.

많은 소프트웨어 회사들이 블르오션을 찾아서 하드웨어 회사들의 영역을 넘보고 있다. 그리고 역으로 하드웨어 회사들 역시 자신들이 그 동안 만들어 놓았던 텃밭을 지키기 위해서, 소프트웨어 회사들이 사용했던 전략을 비슷하게 가져가고 있다. 하지만 이러한 전략들이 제대로 먹히고 있다고 보지는 않는다. 그동안 하드웨어 회사들의 마케팅 전략은 기기의 단가를 낮추거나, 원가를 줄여서 이익을 극대화 하는 것이었고, 이것은 그들만의 리그에서는 통하던 전략이었다.

"S사, 돈 안되는 MP3사업 계속하는 이유"라는 제목으로 이데일리에 기사가 올라와 있는 것을 보았다.
기사 내용을 요약하면, 현재 Apple의 mp3의 시장 점유율은 50%에 육박하고, S사의 5%의 시장 점유율은 시장을 이끌기에는 아주 적다. 그러나 이 사업을 포기하지 않는 이유를 초두 효과(Primary Effect)라고 설명하고 있다. 하지만, 개인적으로는 이 의견이 반드시 맞다고 생각하지 않는다. 어떤 부분은 맞을지 모르지만, 단지 하드웨어 한가지의 우월성에서 차이가 갈리거나, 소비자들의 필요를 채우기에는 부족한 면이 많다.

iPhone의 새로운 모델이 발견될 때마다, 어떤 기능이 추가되었나보다는 애플을 추종하는 무리들에게 우리는 깜짝 깜짝 놀라게된다. 그리고 최근에 미국에서 열렸던 WWCD에서도 5000명이나 되는 개발자들이 행사에 참석하는 것을 보고 또 한번 놀란다. 과연 이만한 지지자들을 모을 만한 회사가 얼마나 될까? 

최근에 발표된 있는 S사의 Z폰과 iPhone에 대한 비교기사들을 보면서 아쉬운 점은, 두 제품의 하드웨어 플랫폼만에 대한 단순 비교가 뒤 따른다는 점이다. 하드웨어의 성능만을 비교하여 "좋다 나쁘다"를 이야기하고 있다. 과연 소비자들이 이러한 비교만을 믿고 제품을 살거라는 생각은 들지 않는다.

그리고 하드웨어의 교체기간도 생각해 볼 문제이다. 
애플을 디바이스를 플랫폼으로 생각하고 있고, 이는 소프트웨어 또는 컨텐츠를 저장하기 위한 그릇으로 생각하고 있다. 지금은 아직 시장이 성장하는 단계이므로 엄청난 수익을 안겨주지 못하지만, 시장이 성숙기에 이를 경우에는 마르지 않는 샘물처럼 애플에게 지속적은 부틀 안 겨줄 거라 예상이 된다. 
하드웨어 교체 주기를 1년으로 생각할고 혁신적은 제품을 지속적으로 시장에 출시하는 것도, 분명한 한계를 보일 것이다. 이는 PC의 예에서 경험적으로 알 수 있다. 이전에는 약 3~4년이 주기로 제품의 Life cycle이 존재하였지만, 이제는 5년~7년을 사용하고 있다. 하드웨어의 사양이 어는 수준 이상으로 좋아지면, 고객들이 이를 교체하려는 필요성이 점점 낮아지기 때문이다.

약 10년 전에는, 인터넷이 부를 가져다 줄거라고 하면서, 여러가지 이론들이 활개를 칠때 소프트웨어의 생산 비용은 0라는 이론들이 나왔고, 이 때문에 굴뚝 산업을 무시하는 경향도 있었다. 그러나 굴뚝 사업과 IT 사업도 결국은 고객에 대한 서비스이다. 그리고 이러한 서비스를 통해서, 이익을 취하는 것이다. 단순의 하나의 제품만을 파는 것이 아니라, 연속적으로 여러가지 제품을 들을 제공할 수 있는 서비스 수단을 고객에게 제공하는 순간에 결과는 판가름 날 것이다.

아마도 이제 전쟁은 시작일 것이다. 최근 iPhone의 한국 출시에 대한 많은 사람들의 관심과 결국은 출시 될거라는 여러가지 정황들이 나타나고 있다. 단지 하드웨어 스펙을 본다면, 이 보다 좋은 제품들이 경쟁적으로 나올 가능성은 현저히 많지만, 그 동안 애플이 만들어 놓은 보이지 않는 플랫폼들을 통한 경쟁은, 즉 소프트웨어적인 경쟁은 아마도 상태를 찾기가 힘들거라 생각된다.





:
Posted by 행복상자