JMS with Spring 1 - What is JMS
허접하니 그냥 참조만...
이번에 설명 할 내용
1. What is Message ? - Message란 무엇이고 왜 사용 하는가
2. JMS Architecture - JMS의 전반적인 아키텍쳐와 사용 모델
3. JMS Element - JMS에서 사용하는 엘리먼트들에 대한 설명
그럼 대충 시작.
1. What is Message?
메시지은 느슨하게 결합된 분산 통신의 한 형태이다. 여기서 통신이란 용어는 소프트웨어 컴포넌트들 간의 구성요소들 사이에 메시지의 교환으로 이해할 수 있다. 메시지 지향 테크놀로지들은 강하게 결합된 통신(TCP network socekst, CORBA or RMI 같은)을 중간요소의 도입을 통해 완하하려고 시도한다. 후자의 접근 방식을 통해 소프트웨어 컴포넌트가 서로 '간접적으로' 통신 할 수 있다. 이러한 메시지의 장점은 보내는 쪽에서 받는 쪽에 대한 정확한 정보가 없어도 가능 하다는 점이다.
메시징의 장점은 이기종 플랫폼 간의 통합과 시스템의 병목현상을 감소 시키고, 확장성을 증가 시키며 변화에 신속하게 대응 할 수 있다.
안좋은 예
간단한 메시징 시스템의 예로 콜센터를 들 수 있다.
고객과 콜센터 직원이 라인을 통해 다이렉트로 통화를 할 경우, 고객이 늘어날 경우에 콜센터 직원이 통화가 가능 할 때까지 계속 다시 전화를 걸어서 통화가 가능한 라인을 찾아야 한다.
좋은 예
위 그림처럼 중간에 경유할 수 있는 Voice Mail Box 같은 장치를 두면, 고객의 요청은 box에 쌓이게 되고 직원은 이것을 확인하고 처리 하면 되기 때문에 고객은 계속 전화를 걸어 통화가 가능한 라인이 있는지 확인할 필요 없이 처리 할 수 있다.
2. JMS Architecture
비즈니스 시스템에 사용되는 응용프로그램들간의 메시징 시스템은 엔터프라이즈 메시징 시스템이나 메시지 지향 미들웨어(Message-Oriented Middleware, MOM)이라고 한다.
대부분의 기업들이 메시징 시스템의 데이터 교환을 destinations라 부르는 가상 채널을 사용한다. 메시지가 전송되고 나면 특정 응용프로그램이 아니라 destination으로(queue 나 topic)에 저장 된다. 아무 응용프로그램이 관심이 있는 destinatin에 등록하여 메시지를 받아 볼 수 있다. 이러한 바법을 통해 메시지를 주고 받는 응용프로그램간의 관계가 느슨하게 유지된다. 메시지를 보내는 쪽이나 받는 쪽이나 어떤식으로든 서로 얽매이게 되지 않고 메시지를 주고 받을 수 있다.
destination
JMS는 응용프로그램 개발자가 같은 API로 다른 시스템들에 사용할 수 있는 JDBC와 유사 하다. 만약 JMS를 준수하여 서비스를 할 경우, JMS API를 통해 공급자가 해당 업체에 메시지를 주고 받을 수 있다. 예를 들어 SonicMQ를 사용하여 메시지를 보내고 IBM WebSphere MQ를 통해 메시지를 처리 할 수 있다.
메시징의 장점
1. 이기종 시스템간의 통합
- 이기종 플랫폼간의 커뮤니케이션과 통합은 메시징의 오래된 사용 방법이다. 메시징을 사용하여 애플리케이션의 서비스를 호출할 수 있고 완전히 다른 플랫폼에서 구현하는 시스템으로 사용할 수 있다. 많은 오픈 소스 및 상용 메시지 시스템은 자바 사이의 매끄러운 연결을 제공하고 다른 언어 및 다른 플랫폼에도 제공한다.
역사적으로 이기종 시스템간의 통합 작업은 많은 방법이 존재 하였다. 정보를 공유하는 데이터베이스를 사용하여 두 이기종 시스템 또는 응용프로그램간에 접근하는 방식이 아직까지 널리 사용되고 있는 방법이다. Remote Procedure CALL은 이종 분산 시스템간의 데이터 및 기능 공유의 또다른 방법이다. 이러한 해결책은 각각 장점과 단점을 가지고 있다. 메시징을 사용함으로써 데이터 및 기능을 애플리케이션이나 서브 시스템을 통해 공유함으로서 결합도를 낮추어 사용한다. 최근 웹 서비스가 또 다른 이기종 시스템 통합을 위한 솔루션으로 등장하였지만 아직 신뢰성이 부족하므로 메시징이 더 좋은 선택이다.(최근에는 웹 서비스도 많이 늘어 나는 추세)
2. 시스템 병목 현상을 감소
- 일반적으로 작업을 처리 하기 위해 많은 수의 프로세스를 만들고 해당 프로세스의 요청 속도를 유지 하기 위해 시스템과 애플리케이션의 병목현상이 발생한다. 가장 많이 볼 수 있는 예로는 튜닝 수준이 낮은 데이터베이스에 연결될 때 까지 기다리는 애플리케이션과 프로세스를 들 수 있다. 이러한 시점에서 응답시간은 악화되고 타이밍이 어긋나게 된다.
한정된 시간내에 처리할 수 있는 용량은 제한되어 있으므로, 이를 처리하기 위해서는 많은 시간이 추가된다.
3. 확장성을 향상
- 병목현상을 감소하는것과 같은 방법으로, 시스템의 전반적인 확장성 및 처리량을 증가 시킬 수 있다.
4. 최종 사용자의 생산성을 높임
- 비동기 메시징을 사용함으로서 생산성을 향상 시킬 수 있다. 동기적으로 처리할 경우 요청을 보내고 처리를 기다리는 동안 많은 시간이 소비 되는데, 비동기 메시징을 사용함으로써 이 시간을 감소 시키고 유용하게 사용 할 수 있다.
5. 아키텍쳐의 유연성 및 민첩성
- 아키텍쳐의 민첩성은 끊임없이 변화하는 환경에 신속하게 대응하는 능력이다. 추상화되고 연결성이 낮은 컴포넌트들에 메시징을 사용하게 되면 소프트웨어, 하드웨어, 비즈니스로직의 변경에 까지 빠른시간에 대응할 수 있다. 메시징을 통해 메시지 공급자나 클라이언트 컴포넌트는 프로그래밍 언어나 플랫폼에 종속족이지 않기 때문에 유연하고 민첩한 대응을 할 수 있다.
2.1 메시징 모델
JMS는 두가지 타입의 메시징 모델을 지원한다.
Point-to-point, publish-and-subscribe
이 메시징 모델은 메시징 도메인이라고 불리기도 한다. 줄여서 p2p와 pub/sub 각각 불리운다.
가장 간단한 의미로 pub/sub는 one-to-many 브로드 캐스트 메시징을 위한거고 p2p는 one-to-one 딜리버리 메시징이다.
JMS 관전에서 메시징 클라이언트들은 JMS 클라이언트라고 부르고 메시징 시스템은 JMS 프로바이더로 불리운다. JMS 애플리케이션은 많은 수의 JMS 클라이언트와 일반적으로 하나의 JMS 프로바이더로 구성된다.
추라고, 메시지를 제공하는 JMS 클라이언트는 message producer라고 하고, 메시지를 받는 쪽을 message consumer 라고 부른다. JMS 클라이언트가 각각 consumer나 producer가 될 수 있다. consumer 와 producer라는 용어를 사용할 때 JMS 클라이언트가 각각 메시지를 consume 하거나 produce하는걸 의미 한다.
2.1.1 Point-to-Point
- p2p 메시징 모델은 JMS 클라이언트가 메시지를 동기 및 비동기 방식으로 queue라고 불리우는 가상 채널을 경유하여 전송하거나 받을 수 있다. p2p모델에서 message producer는 sender, message consumer 는 receiver로 불리운다. p2p 메시징 모델은 Pull 기반이거나 클라이언트에게 자동으로 push되는 Polling 기반 모델이다. p2p 메시징 모델의 구분되는 특징중에 하나는 메시지는 queue에 전송되고 다른 수 많은 receiver가 같은 메시지를 받기위해 대기하고 있어도, 하나의 receiver에 하나씩 전송 된다는 점이다.
Point-to-point 메시징은 "발생하고 잊어 버리는" 비동기 메시징을 지원하는것 뿐만 아니라 동기정 요청/응답 메시징을 지원한다. Point-to-point 메시징은 publish-and-subscribe 모델보다 좀 더 결합할려는 경향이 있다. 보내는 쪽에서 메시지가 어떻게 사용되기 위해서 전송되는지 알고 누가 메시지를 받는지 알기 때문이다. 예를 들어, 전송하는 쪽에서 주식 거래를 하기 위해 큐에 내용을 전송하고 거래 확인 번호를 포함한 내용을 기다릴 때 이다. 이 예제에서 메시지를 보내는쪽은 메시지를 받는쪽이 거래요청을 처리할 것이라는 것을 알고있다. 다른 예는 시간이 오래걸리는 레포트 생성을 비동기적으로 요청할 때다. 보내는 쪽에서 레포트를 위한 요청을 만들고 레포트가 준비 되면 알림 메시지가 보내는쪽에게 전송된다. 이 예에서 센더는 보내는 쪽은 받는쪽에서 메시지를 보고 레포트를 생성하러 갈 것이라는 것을 알고있다.
Point-to-Point 모델을 로드밸런싱을 지원한다. 다중 리시버가 같은 큐에서 수신 대기 하고 있고 따라서 부하가 분산된다. 그림 1-4처럼 JMS provider는 메시징을 큐에서 관리한다. 각각 메시지가 한번에 한개씩 리시버 그룹에서 처리가 가능한 리시버가 처리하는것을 보장한다. JMS 스펙은 분산 메시징 처리를 강요하지 않는다. 비록 몇몇 JMS 벤더들이 이 로드밸런시을 구현하고 있지만. Point-to-point은 메시지가 읽혀지기 전에 대기열의 내용을 볼 수 있는 대기열 브라우저 같은 다른 기능을 제공 한다. 이 브라우저 컨셉은 pubish-and-subscribe 모델에서는 지원되지 않는다.
2.2.2 Publish-and-Subscribe
pub/sub 모델에서 메시지는 topic이라고 불리는 가상 채널을 통해 공급된다. Message producers 는 publishers, message consumers는 subscribers라고 불리운다. p2p모델과는 달리 topic을 통해 공급되는 메시지는 여러 subscribe에게 전달 될 수 있다. 이 방법은 가끔지 메시지를 브로드캐스팅하기위해 추천하는 방법이다. 모든 subscriber는 복제된 같은 메시지를 받는다. pub/sub 메시징 모델은 대형 푸쉬 기반 모델이다. 메시지는 consumer들에게 새로운 메시지 확인을 위해 요청및 poll을 할 필요 없이 자동적으로 broadcast 되는 모델이다.
pub/sub 모델은 p2p모델 보다는 결합도가 낮다. publisher는 많은 subscribers들이 있고, 이들이 메시지를 가지고 무엇을 할지 알지 못한다.
3. JMS Element
기본적인 아키텍쳐 설명은 이정도 까지만 하고, 자주 사용되는 용어에 대해서 정리해보자.
이 내용은 http://en.wikipedia.org/wiki/Java_Message_Service에 잘 정리 되어 있다.
- JMS provider : Message Oriented Middledware(MOM)을 위한 JMS 구현체. Java JMS의 구현체 이거나 이기종 MOM의 아답터 역할도 한다.
- JMS client : 메시지를 전송하거나 받는 애플리케이션
- JMS producer/publisher : 메시지를 만들고 전송하는 클라이언트
- JMS consumer/subscriber : 메시지를 받는 클라이언트
- JMS message : JMS 클라이언트 사이에 전송되는 오브젝트
- JMS queue : 메시지를 전거나 메시지를 읽기 위해서 메시지가 대기중인 영역. 메시지의 전송 순서는 보장 하지 않고, 오직 한번 읽는 다는 것만 보장한다.
- JMS topic : 다양한 subscriber들에게 메시지를 전송하기 위한 방법.
리소스 지향 아키텍쳐 설계 어프로치
REST한 아키텍쳐를 구현하기 위한 한가지 방법.
http://en.wikipedia.org/wiki/Resource-oriented_architecture
헐.. 위키 주소가 정말 RESTFul 한 URI 구나. !!
아무튼..
1. 웹 서비스에서 제공할 데이터를 특정한다.
2. 데이터를 리소스로 나눈다.
3. 리소스에 URI로 이름을 부여한다.
4. 클라이언트에 제공할 리소스의 표현을 설계한다.
5. 링크와 폼을 이용해 리소스와 리소스를 연결한다.
6. 이벤트의 표준적인 코스를 검토한다.
7. 에러에 대해 검토한다.
from. 웹을 지탱하는 기술.
SRP(Single responsibility principle)는 객체 지향 설계에서 더욱 중요한 개념이다. 또한 이해하고 지키기 수월한 개념이기도 하다. 하지만 이상하게도 SRP는 클래스 설계자가 가장 무시하는 규칙 중 하나다. 우리는 수많은 책임을 떠안은 클래스를 꾸준하게 접한다. 왜일까?
소프트웨어를 돌아가게 만드는 활동과 소프트웨어를 깨끗하게 만다는 활동은 완전히 별개다. 우리들 대다수는 두뇌 용량에 한계가 있어 "깨끗하고 체계적인 소프트웨어"보다 "돌아가는 소프트웨어"에 초점을 맞춘다. 전적으로 올바른 태도다. 관심사를 분리하는 작업은 프로그램만이 아니라 프로그래밍 활동에서도 마찬가지로 중요하다.
문제는 우리들 대다수가 프로그램이 돌아가면 일이 끝났다고 여기는 데 있다. "깨끗하고 체계적인 소프트웨어"라는 다음 관심사로 전환하지 않는다. 프로그램으로 되돌아가 만능 클래스를 단일 책임 클래스 여럿으로 분리하는 대신 다음 문제로 넘어가 버린다.
게다가 많은 개발자는 자잘한 단일 책임 클래스가 많아지면 큰 그림을 이해하기 어려워진다고 우려한다. 큰 그림을 이해하려면 이 클래스 저 클래스 수없이 넘나들어야 한다고 걱정한다. 하지만 작은 클래스가 많은 시스템이든 큰 클래스가 몇 개뿐인 시스템이든 돌아가는 부품은 그 수가 비슷하다. 어느 시스템이든 익힐 내용은 그 양이 유사하다. 그러므로 고민할 질문은 다음과 같다. "도구 상자를 어떻게 관리하고 싶은가?" 작은 서랍을 많이 두고서 기능과 이름이 명확한 컴포넌트를 나눠 넣고 싶은가? 아니면 큰 서랍 몇 개를 두고서 모두를 던져 넣고 싶은가?"
규모가 어느 수준에 익르는 시스템은 논리가 많고도 복잡하다. 이런 복잡성을 다루려면 체계적인 정리가 필수적이다. 그래야 개발자가 무엇이 어디에 있는지 찾는다. 그래야 (변경을 가할 때) 직접 영향이 미치는 컴포넌트만 이애하면 충분하다. 큼직한 다목적 클래스 몇 개로 이뤄진 시스템은 (변경을 가할 때) 당장 알 필요가 없는 사실까지 들이밀어 독자를 방해한다.
강조하는 차원에서 한 번 더 말하겠다. 큰 클래스 몇 개가 아니라 작은 클래스 여럿으로 이뤄진 시스템이 더 바람직하다. 작은 클래스는 각각 책임이 하나이며, 변경할 이유가 하나이며, 다른 작은 클래스와 협력해 시스템에 필요한 동작을 수행한다.
프로젝트가 실패하는 이유.
죽음의 행진.. 우리나라로 따지면 무한 야근 막 이런거 -ㅅ-;;
다행히 입사한지 1년이 넘었지만 야근은 한번도 안했다.
되도록 일찍 퇴근하려고 노력하고, 집에 가면 기술 서적이나 방법론 개념 책들을 조금씩 읽는다.
많이 읽으면 한달에 2~3권, 아니면 1권.. 출퇴근할때나 잠잘때는 소설 들도 읽고.
아무튼 아래 컬럼은 개발자나 PM등 관리층에게도 도움이 되는 글이다.
야근을 피하고 윤택하고 아름다운 개발자 생활을 만끽하자 :-)
실패하는 이유.
멍청하고 무지한 관리층에게 고하노라, 죽음의 행진은 다음과 같은 이유로 실패하느니...
* 실패를 목표로 삼는다 - 처음부터 할 일은 너무 많고 시간이 너무 없는 프로젝트다. 당연히 실패한다.
* 편법을 부추긴다 - 일정에 쫓기면 당연히 편법이 난무한다. 그런데 안타깝게도 편법은 품질을 낮추고 위험을 높인다. 단기간에 작은 업무라면 무사히 넘어갈지도 모르겠다. 그러나 프로젝트가 지연되면 품질은 낮아지고 위험은 커져 결국은 문제를 일으킨다.
* 생각할 시간이 없다 - 효과적으로 일하려면 여유 시간이 필요하다. 읽고, 생각하고, 토론할 시간이 있어야 한다. 이런 시간이 없으면 맨 처음 떠오르는 추측을 적용한다. 맨 처음 생각이 옳을 확률은 낮으므로 당연히 설계와 계획이 엉성해지고 품질이 떨어진다. 결국 치명적인 결함이 드러나거나 완전히 뒤엎어야 하는 사태가 발생한다.
* 대화할 시간이 없다 - 모든 문제는 대화 단절과 오해에서 비롯된다고 주장해도 과언은 아니다. 심지어 우수한 팀도 대화 부족으로 실패하는 경우가 흔하다. 업무량이 과도하고 여유가 없는 환경에서는 대화가 줄어들고 대화의 효율성도 떨어진다. 대화 단절이 심할수록 프로젝트는 성공하기 어렵다.
* 긴장, 스트레스, 기능 장애가 발생한다 - 일정에 쫓겨 마음이 급하면 가장 먼저 너그러움이 사라진다. 업무에 사적인 감정이 개입된다. 다른 팀원의 실수를 부풀리고 곡해한다. 목소리가 높아지고 급기야는 대화가 끊긴다.
* 사기가 떨어지고 팀이 와해된다 - 가족과 친구들에게 소홀하면서 긴장과 스트레스 속에서 장시간 이하면 팀이 신체적으로나 정신적으로 지친다. 프로젝트가(당연히) 일정과 품질 목표를 못 맞추면 팀원들은 한순간 인내심을 잃는다. 운이 좋으면 프로젝트가 끝날 즈음 그룹을 옮기느 정도로 그친다. 운이 나쁘면 회사를 뜨거나, 이혼을 당하거나, 건강을 해치거나, 위험한 뭔가에 중독되는 지경에 이른다.
참고로, 팀원이 자발적으로 늦게 남아 일하는 경우를 죽음의 행진으로 오해하는 관리자도 많다. 죽음의 행진은 역학이 전혀 다르다. 죽음의 행진에 내몰리는 팀원은 어쩌 수 없이 늦게까지 일한다. 반면, 스스로 늦게까지 일하는 팀원은 대개 일이 좋아서다. 필요하면 여유 시간도 충분히 갖는다. 일정에 쫓기지 않으므로 편법으로 땜질할 이유도 없다.
* 회사를 불신하게 된다 - '죽음의 행진 = 뭔가 잘못되어 나타나는 현상'이라는 공식은 두말하면 잔소리다. 죽음의 행진을 지켜보는 직원과 고객과 협력업체는 팀에게서 헌신이 아니라 무능함을 느낀다. 진짜 문제는 덮어두고 죽어라 일해 봤자 회사 위신과 이미지만 구겨진다.
* 문제를 해결하지 못한다 - 컴퓨터 앞에 오래 앉아 있다고 근본적인 문제, 즉 '할 일은 많은데 시간이 부족하다' 라는 문제가 사라지지 않는다. 근본적인 문제를 해결하지 않는 한 상황은 나아지지 않는다.
* 선택의 여지가 줄어든다 - 시간을 들여서 제대로 설계하고 계획하지 않으면 제품에 치명적인 결함이 생기고 대다수 작업을 다시 해야 한다. 팀은 대화가 끊기고, 오해가 난무하며, 서로 잡아먹으려고 으르렁거린다. 사기는 떨어지고, 출시 능력을 의심받으며, 그러고도 일정과 품질 목표를 놓친다. 물론 원래 문제는 그대로 남아 있따. 이런 지경에 이르면 프로젝트는 선택의 여지가 줄어든다. 결국 품질을 낮추고, 일정을 늦추고, 죽음의 행진을 계속 하는 수밖에 없다. 멋지지 않은가?
전환점
자, 할 일은 너무 많은데 시간이 너무 없다. 어떻게 해야 할까? 현실적인 측면에서 답은 대단히 쉽다. 할 일이 너무 많은 이유와 시간이 너무 없는 이유를 찾아내면 된다.
"일정와 요구사항이 위에서 내려왔거든요"는 답이 아니다. 왜 그런 일정과 요구사항이 내려왔을까? 일정과 요구사항을 지키지 못하면 관리층은 어떻게 대응할까? 일정을 늦춰줄까? 얼마나? 요구사항을 쳐낼까? 어떤 기능을? 프로젝트 역학을 근본적으로 바꿀 방법은 없을까? 일단 위에다가는 주어진 날짜와 요구사항을 목표로 삼겠다고 말한 후 자체적으로 최악의 상황을 계획한다.
즉, 최악의 상황을 고려해 계획을 세운다. 반드시 지킬 최후 일정과 반드시 넣을 최소 기능을 계획으로 세워본다. 그래도 시간이 부족하다면 관리층에게 경고한다. 이런 프로젝트는 애당초 가망이 없다. 최악의 시나리오가 충분히 달성 가능하다면 여기에 총력을 기울인다. 팀원들에게 목표를 초과하면 3.5점 이상을 목표에 못 미치면 3.0점 미만을 주겠다고 말한다.(마이크로 소프트에선 4.5점 만점)
남들이 가지 않은 길
이로써 팀은 죽음의 행진에서 벗어나고, 상황을 개선할 여유 시간이 생긴다. 십중팔구 목표도 초과 달성한다. 그러면서도 편법을 쓰거나, 미숙한 결정을 내리거나, 서로 잡아먹는 일도 없다. 필요한 기능을 기한 내에 완료하면서 동시에 협력업체와 고객에게서 신뢰도 얻는다.
그럴 듯하게 들리지만 감정적으로 쉽지 않은 일이다. 최악의 상황을 계획하려니 프로젝트를 포기하는 느낌이 든다. 유약한 겁쟁이가 되는 듯하다. 난관을 극복할 능력이 없다고 자인하는 꼴이 아닌가? 역설적이게도 실제는 정반대다.
위험을 회피하는 행동이 오히려 유약하고 비겁하다. 최악의 가능성을 무시하는 태도가 오히려 기만적이고 무책임하다. 용기를 보여라. 진신을 인정하라. 영리한 태도로 협력업체와 고객과 직원을 고통에서 구하라. 팀과 삶과 자신감을 보호하면서 프로젝트를 성공으로 이끌어라.
Utility Class
위키 디피아
일반적으로 자주 쓰이는 메소드들의 집합으로 스태틱 메서드들로 구현되어 있다.
유틸리티 클래스를 생성할 때는 private 생성자를 작성하여 Instance를 생성을 방지 하자. 스태틱 메서드들 뿐이기 때문에 인스턴스 생성이 필요 없다.
Art of Science.
우리는 과학이 예술이라는 사실을 잊어 버렸다.......중략
공학에 예술적인 감각과 열정을 되돌려야 한다.
재능, 자신감, 열정은 도구를 쓸 줄 아는 사람에게 나타나는 특성이다.
이런 특성이 부족한 사람은 아무리 좋은 도구와 기법을 안겨줘도 소용이 없다.
Frosch 1969 - "A New Look at Systems Engineering."
IEEE Spectrum, September 1969; Robera A, Frosch.
명령을 내리는 관점.
수학은 "그것이 무엇인가(What is)"의 개념을 정확하게 다루는 일에 바탕이 된다. 그와 달리, 컴퓨터 계산법은 "그것을 어떻게 하는가(How to)" 라는 개념을 정확히 다루는 일에 토대가 된다.
- 컴퓨터 프로그램의 구조와 해석 -
프로그램, 제품, 시스템, 시스템 제품
코드의 줄 수와 팀 크기만이 프로젝트의 크기에 영향을 미치는 것은 아니다. 최종적인 소프트웨어의 품질과 복잡성이 보다 미묘한 영향을 미친다. 원래의 기가트론은 작성하고 디버깅하는 데 한 달이 걸렸을 뿐이었다. 그 프로그램은 한 사람에 의해서 작성되고 테스트되고 문서화된 단일 프로그램이었다. 만약 2,500줄짜리 기가트론이 한 달 걸렸다면, 왜 25,000줄로 확장된 기가트론은 스무 달이 걸렸을까?
가장 간단한 소프트웨어의 종류는 그 프로그램을 작성한 한 사람 또는 몇 사람에 의해서 사용되는 단일 "프로그램"이다.
보다 정교한 프로그램의 종류는 원래의 개발자가 아닌 다른 사람들에게 의해서 사용될 목적으로 만들어진 프로그램, 즉 소프트웨어 "제품"이다. 소프트웨어 제품은 제품이 작성된 것과는 다른 환경에서 사용된다. 따라서 제품이 릴리즈되기 전에 광범위하게 테스트되고 문서화되며, 다른 사람에 의해서 유지 보수될 수 있다. 소프트웨어 제품은 소프트웨어 프로그램보다 개발하는데 약 3배의 비용이 든다.
함께 작동하는 프로그램 그룹을 개발할 때에는 또 다른 정교함이 요구된다. 그런 그룹을 소프트웨어 "시스템"이라고 부른다. 시스템 개발은 통합되는 부분들 사이의 인터페이스를 개발하는데에 따른 복잡성과 주의가 요구되기 때문에 간단한 프로그램을 개발하는 것보다 좀 더 복잡하다. 전체적으로, 시스템도 간단한 프로그램을 개발하는 것보다 3배 정도의 비용이 든다.
"시스템 제품"이 개발될 때에는, 제품과 시스템의 여러 부분들을 다듬어야 한다. 따라서 시스템 제품은 간단한 프로그램보다 9배 정도의 비용이 든다.(Brooks 1995, Shull 외. 2002)프로그램과 제품, 시스템, 시스템 제품 간의 매끄러움과 복잡성 간의 차이를 제대로 평가하지 못하는 것이 견적 오류의 일반적인 원인이다. 예를 들어, 프로그램을 작성해 본 경험이 있는 프로그래머가 자신의 경험을 토대로 시스템 제품을 작성하기 위한 일정을 추정하게 되면 거의 10배 정도 낮게 추정할 수 있다. 만약 2K 프로그램을 개발하기 위해서 걸리는 시간을 추정하기 위하여 2K줄짜리 코드를 작성했던 경험을 사용한다면, 여러분이 예상한 시간은 실제로 프로그램을 개발하면서 들어가는 모든 활동들을 수행하기 위해서 필요한 전체 시간의 65%일 뿐이다.
2K줄짜리 코드를 작성하는 것은 2K줄을 포함하고 있는 전체적인 프로그램을 작성하는 것 만큼 오랜 시간이 걸리지 않는다. 만약 구현이 아닌 활동 등에 걸리는 시간을 고려하지 않는다면, 구현은 여러분이 예측한 것보다 50% 정도의 시간이 더 걸릴 것이다.
크기가 커질수록, 구현은 프로젝트에 들어가는 전체적인 노력에서 보다 작은 부분이 된다. 만약 여러분의 견적을 구현에서의 경험에만 기초한다면, 견적 오류는 증가할 것이다. 만약 32K 프로그램을 개발하는 데 걸리는 시간을 추정하기 위해서 2K 구현 경험을 사용했다면, 여러분의 견적은 단지 필요한 전체 시간의 50%가 되고, 개발은 추정한 것보다 100%의 시간이 더 걸릴 것이다.
여기서의 견적 오류는 전적으로 더 큰 프로그램을 개발하는 데 있어서 크기가 미치는 영향을 이해하지 못했기 때문일 것이다. 또한, 만약 단일 프로그램이 아닌 제품에 요구되는 추가적인 섬세함 정도를 고려하지 못한다면, 오류는 3배 이상으로 증가할 수 있다.
아무래도 가장 중요한 듯 싶다.
나는 항상 일정에 쫓기 업무는 싫어서
항상 내 일정을 내 스스로 잘 조정할려고 노력하는 타입이다.
항상 퇴근 시간이 되면 그 전에 했던 일들을 정리하고
내일 그리고 이번주에 해야할 일 전체적인 진행상황들을
달력을 보면서 머릿속으로 정리한다.
일반적으로 쓰이는 버전 번호 규칙에 대해서 알아보자.(자바쪽)
보통 버전은 다음과 같은 네 가지 부분으로 구성된다.
major.minor.service.qualifier
각각의 의미에 대해서 알아보자
- major(주버전) : 주 버전의 변경은 하위 호환이 보장되지 않는 등의 매우 큰 변화를 의미한다.
- minor(부버전) : 부 버전의 견경은 플러그인의 새 버전이 기존 버전과 하위 호환은 되지만 기능과 API가 추가 되었다는 의미이다.
- service(서비스버전) : 서비스 버전은 기존 버전에 대해 버그 수정 또는 사소한 구현(숨겨진)이 추가 되었다는 의미이다.
- qualifier(수식자) : 수식자는 런타임에서는 인식하지 않는다. 수식자는 표준 문자열을 통해서 비교된다.
이클립스 및 거의 모든 jar 파일들의 위의 버전 번호 규칙을 사용한다.
이 버전 번호 규칙을 알고 있으면 이전 버전에 바뀐것이 무었인지 명세를 살펴보지 않아도
어느정도 감을 잡을 수 있기 때문에 도움이 된다.
출처 : 이클립스 RCP
의사코드 프로그래밍 프로세스.
CODE COMPLETE 9장.
의사코드 프로그래밍에 대해 이야기 하고 있다.
뭐.. 간단히 슈도 코드를 사용해서 작성하고 이를 코드로 바꾼다는 이야기.
나도 아직 경험이 적기 때문에 완벽히 적용하고 있지는 않지만 적용하기 위해 노력해야 겠다.
요즘에야 TTD 나 리팩토링 기법도 자주 사용되고 있지만,
그전에 슈도 코드로 미리 작성을 해보고 이를 가지고 TTD를 적용하여 개발 하는게 좋은 것 같다는 생각이 든다.
가장 중요한 건 "컴파일 한 번만 더" 증후군에 걸리지 않는다.
공감하는 내용.
이는 조급하게 오류를 유발할 수 있는 변경을 하게 만들고,
길게 봤을 때 더 많은 시간이 걸리게 한다.
루틴이 맞다는 확신이 들 때까지 컴파일 하지 않도록 하자.
웹 브라우저 테스트 해보기 전에 지금 무엇을 테스트하려는지 명확히 하고 지금 테스트 하려는 코드가 올바르게 동작 하는지 충분한 생각을 한 후 테스트 해보도록 하자.
뒷 부분 요점 정리를 옴겨 보면.
- 클래스와 루틴의 구현은 반복적인 경향이 있다. 특정한 루틴을 구현하는 도중에 얻게 되는 내용들이 클래스의 설계에 영향을 미치는 경향이 있다.
- 훌륭한 의사코드를 작성하기 위해서는 이해 가능한 영어를 사용하고, 단일 프로그래밍 언어에 특화된 기능들을 피하고, 의도 수준에서 작성해야 한다.( 어떻게 처리할 것인지 보단느 설계가 무엇을 하는지 기술한다.)
- 의사코드 프로그래밍 프로세스는 상세 설게에 유용한 도구이며 코드 작성을 쉽게 만든다. 의사코드는 곧바로 주석으로 변환되며, 변환된 주석은 정확하고 유용하다.
- 여러분이 생각한 첫 번째 설계로 결정하지 않는다. 의사코드에서 여러 가지 접근 방법을 이용하여 반복하고 코드를 작성하기 전에 가장 좋은 접근 방법을 선택한다.
- 각 단계에서 자신의 작업을 검사하고 다른 사람들도 여러분의 작업을 검사하도록 한다. 그렇게 하면, 가장 적은 노력을 들였을 때 가장 적은 비용 수준에서 실수를 잡을 수 있을 것이다.