수안이의 컴퓨터 연구실

  • Mainpage
  • About Me
  • Tags
  • Metapage
  • Notice
  • Location
  • Keywords
  • Guestbook
  • Admin
  • Write an Article
  • Total | 1693802
  • Today | 153
  • Yesterday | 588

2 Articles, Search for '컨테이너'

  1. 2007/05/18 EJB 기반 프로젝트 수행 가이드 ②
  2. 2007/05/17 표준 템플릿 라이브러리(STL, Standard Template Library)를 왜 사용해야 하는가?
Programming/Java2007/05/18 11:22

EJB 기반 프로젝트 수행 가이드 ②

세션빈에서의 트랜잭션 관리

김주현 (ERP 개발자)  
2004/03/30        

① 세션빈에서의 DB 접근전략 및 엔터티빈 사용시 주의사항
② 세션빈에서의 트랜잭션 관리
③ 비즈니스 프로세스 구현 최적화하기
④ 능률 높여주는 유틸리티를 사용하자

지난 강좌에서는 세션빈 내에서 DB를 핸들링하는 데에는 JDBC 드라이버를 이용한 Connection 객체를 사용하는 방법과, 엔터티빈을 이용하는 방법이 있다고 언급했다. 중요한 점은 두가지 방법을 혼용하는 것이 아니라 엔터티빈 사용시 발생하게 되는 문제점을 미리 알고 엔터티빈 사용을 지양하자는 것이다.

지난번 강좌에 이어 엔터티빈 사용을 지양할 수 밖에 없는 사례 한 가지를 더 예로 들겠다.

통상 SI 프로젝트에서 인사시스템과 같이 개인의 정보보안이 엄격히 다루어져야 하는 성격의 시스템인 경우, 업무 전반 모두를 웹기반으로 구현하지는 않는다. 물론 웹으로 구현하는 것과 보안과는 별개의 문제이지만, 아직도 공기업 등에서는 웹기반 구현을 꺼리는 경우가 많기 때문이다.

급여계산 및 업무평가점수계산 등 민감한 성격의 정보를 다루는 프로그램은
클라이언트/서버(C/S) 환경으로 구축돼 업무 담당자만 사용 할 수 있도록 하고, 웹으로는 일반사원들이 자신의 정보를 확인하는 조회성 프로그램만으로 구성되도록 요청하는 사례가 많다.

조회성 기능만 갖고 있는 웹기반 프로그램을 설계한다면, 설계자는 DB의 레코드를 SELECT하고 화면에 보여주는 기능만을 수행하므로 쿼리보다는 엔터티빈을 활용하겠다는 기준을 세우고, 실제 개발도 엔터티빈을 이용해 진행하게 된다.

C/S 환경 시스템과 웹프로그램은 서로 업무 범위 및 구축된 환경만 다를 뿐이지 물리적으로 같은 DB를 사용하고 있다. 이러한 환경에서 간혹 발생하는(주로 동시사용자수가 증가할 때 발생한다) EJB 컨테이너의 ‘NoSuchObjectException’ 장애물을 알아둬야 한다.

C/S 프로그램으로 업무를 하는 담당자와 일반 사용자가 같은 레코드를 조회한 상태에서, 담당자가 해당 레코드를 수정 혹은 삭제했고, 웹의 클라이언트 모듈이 해당 레코드를 표현하는 엔터티빈을 계속 참조하고 있는 상황이라면 NoSuchObjectException을 보게 될 것이다.

이 Exception을 던지는 일은 EJB 컨테이너의 기능 중 하나로 엔터티빈의 객체정보와 실제 DB의 정보가 일치하지 않을 경우 동작하게 된다. EJB 컨테이너는 실제 DB와 엔터티빈 객체를 동기화하고 있기 때문에 다른 세션이 자신이 참조하고 있는 DB의 레코드를 변경했을 경우 Exception을 던지는 것이다.

이 Exception이 발생하면 이를 해결하는 방법은 컨테이너가 참조하고 있는 엔터티빈을 핫디플로이 시켜서 객체를 다시 참조케 하거나, 핫디플로이 방법을 쓸 수 없다면 EJB 서버를 RESTART하는 수 밖에 없다.

컨테이너가 NosuchObjectException을 던질 경우 자동으로 엔터티빈을 Passivate시키고 Activate시키면 편리하겠지만 아쉽게도 그런 기능은 없다. 개발자가 향후에 NosuchObjectException이 생기지 않도록 프로그램마다 빈의 라이프싸이클을 제어하는 부분을 추가하는 방안도 생각해 볼 수 있겠지만 그 작업은 시간 소모가 크다.

해당 엔터티빈의 실행 중 정보를 갖고 있는 XML 데이터의 값 중에서 이러한 에러를 일으키지 않도록 해주는 속성이 무엇인지 안다면, XML 데이터의 값을 고치고 다시 디플로이 하는 방법도 있겠다.

하지만 개발자 입장에서는 본인의 판단 착오와는 전혀 관련이 없는 에러를 맞닥뜨리게 된 것이며, 이미 에러를 발견한 이후에 작업을 하는 것이므로 이미 사용자의 프로그램에 대한 신뢰도가 떨어져있는 상황이겠다. 또한 시스템 내의 모든 엔터티빈을 찾아내 작업을 하기도 꽤 번거로운 일일 것이다.

컨테이너의 동기화 기능이 유발시키는 NoSuchObjectException과 엔터티빈과 매핑되는 테이블이 컬럼이 추가되는 등의 변경 사항이 있을 시 엔터티빈의 소스를 고쳐 다시 디플로이 해야 한다는 문제점으로 인해, 항상 시간에 쫓기는 프로젝트 개발자 입장에서는 엔터티빈의 스펙때문에 자신의 보폭이 좁아지는 느낌을 받을 것이다
.
그리하여, 기존 시스템은 엔터티빈을 이용하되 추가 프로젝트에서는 엔터티빈을 전혀 사용하지 않고, DB핸들링은 100% SQL문으로 처리하고 있는 싸이트도 생기게 된다.

엔터티빈을 쓰지 않으면 DB의 테이블마다 SELECT, DELETE, INSERT, UPDATE 등의 쿼리를 일일이 개발자가 생산해야 하지 않느냐는 의견도 나올 수 있으나 프로젝트 프로토타이핑 단계시점 등에 테이블당 쿼리문을 자동으로 생성시켜주는 간단한 유틸 프로그램을 직접 만들어 사용한다면 생산성이 비약적으로 높아질 수 있다.(4회 강의에서 이 유틸을 소개할 예정이다.)

엔터티빈 사용시 발생하게 되는 문제점에 대한 이야기는 여기서 마무리하고, 초점을 세션빈으로 돌리자. 세션빈 내에서 비즈니스 처리를 할 때 유의해야 할 점이 무엇인지 알아본다.

비즈니스 프로세스와 트랜잭션
하나의 비즈니스 프로세스가 처리될 때 가장 중요하게 지켜져야 할 사항은
트랜잭션이 결함없이 처리되어야 한다는 점이다. 예를 들어 보험금 수납시에 보험담당자의 실적이 체크됨과 동시에, 회계장부에 보험금이 기록되어야 하는 [보험금수납]이란 이름의 업무정의가 있을 경우, 이 업무가 성공적으로 완료되었다고 판단할 수 있는 것은 단 2가지 외에는 없다.

실적도 체크되지 않고 장부에도 기록되지 않은 경우와, 실적 체크와 장부 기록 둘 다 성공한 경우다. 이 외 둘 중 하나만 성공한 경우는 트랜잭션이 실패한 것이다. 시스템 운영상 결코 발생해서는 안되는 치명적인 결함이다.

세션빈이 수행하는 메소드안에서 반드시 트랜잭션이 성공해야 함은 아무리 강조해도 지나치치 않을 것이다.


EJB 컨테이너와 트랜잭션
EJB 개발자들은 세션빈의 메소드 단위로 트랜잭션 레벨을 설정할 수 있다는 것을 알고 있다. 또한 컨테이너가 개발자가 설정한 트랜잭션의 레벨에 따라 메소드 내의 트랜잭션을 하나로 묶어준다는 것도 알고 있다.

EJB의 실행중 속성정보를 갖고 있는 XML 파일안을 조작함으로써 트랜잭션 관리가 필요한 메소드를 지정할 수 있고(기본값은 ALL이다), 레벨 또한 조작할 수 있다.
설정 레벨은 REQUIRED로 지정한다(트랜잭션을 관리할 필요가 없는 업무정의가 존재하는 경우는 없다고 봐도 좋다).

컨테이너는 이 두 가지 정보를 가지고 메소드 시작시점부터 완료시점까지 Exception이 발생하게 되면 레벨이 REQUIRED일 경우 Exception발생 전까지 수행했던 작업을 모두 롤백시킨다.

설정레벨을 하위로 조정하면 Exception을 던지되 롤백시키지는 않는 현상이 벌어진다. 그러므로 이 XML의 기본값을 고치는 경우는 없고, 고쳐서도 안된다. VisualCafe와 같이 자동으로 EJB의 XML을 생성시켜주는 툴에서부터 모두 이 옵션을 기본적으로 REQUIRED로 설정하고 있다.

이렇게 트랜잭션을 컨테이너가 메소드 단위로 관리하므로 개발자 입장에서는 명시적으로 트랜잭션을 ON/OFF 하는 기능을 구현할 필요 없이 일정부분 태스크가 줄어든 상태로 볼 수 있다.

하지만 메소드 내에서 Connection을 씀에 있어 언제 Connection을 얻어오고 반환해야 할 지, 또는 Connection 객체를 몇 개 선언해 생성시켜 쓸 것인지와 같은 고민들은 컨테이너의 기능과 별개로 전체 프로젝트에 일관성 있게 적용되어야 할 표준으로 정해져야 하며, 이는 설계자와 개발자의 몫이다.

Connection 객체 핸들링을 하는 기준
Conection 객체를 어느 클래스가 생성하며 반환할 것인가, DB 래퍼 클래스의 메소드와 통신할시 Connection 객체를 넘길 것인가 말 것인가, 넘긴다면 어떤 방법으로 넘기는가에 대한 기준을 세워야 한다.

세션빈 Connection을 선언하고 생성시켜 얻어오는 주체는 1회 강의에도 말했듯이 세션빈 클래스이다. 세션빈 클래스 안에서 Connection 객체는 전역변수로 선언하지 말아야 한다.

각각의 메소드마다 지역변수로 선언하여 사용하는 것이 효과적이다. 또한 메소드안의 프로세스가 진행 완료됐을 경우, finally 절에서 반드시 Connection을 반환해야 하는 것도 중요한 원칙 중 하나다. 커넥션을 얻어올 때, SQLException을 던져야 하므로 try, catch문을 사용하게 되는데, finally 절에서 반드시 커넥션을 반환하도록 하자.

생성된 Connection 객체는 DB와의 작업을 모두 한 이후 반드시 close 메소드를 통해 닫혀져야 하는데, Connection 객체가 반환되지 않는 경우 심각한 시스템 자원낭비를 유발하게 된다. 이는 곧 프로그램의 운용성능 저하로 이어진다.

Connection 객체생성은 언제나 close() 메소드와 쌍을 이루어야 한다는 식의 사고습관을 가져야 하겠다.

다음으로 언급할 것이 DB 래퍼 클래스와의 통신 패턴이다. DB 래퍼 클래스는 DB에 SELECT, INSERT, DELETE, UPDATE 쿼리를 전달하는 역할을 하는 메소드 집합체로써, DB와 가장 가까운 층이다.

세션빈 메소드는 복잡한 비즈니스 프로세스를 구현하게 되는데, 메소드 시작 부터 끝까지 Connection 객체를 통한 쿼리실행이 모두 그 안에 나열돼 있다면 유지보수 하는 사람 뿐 아니라 개발하는 당사자조차도 가독하기 힘들다.

따라서 DB 래퍼 클래스를 만들어서 쿼리실행에 필요한 인자(사용자가 입력한 조회조건 또는 사용자가 입력한 정보)를 세션빈이 전달하고, 실행 결과를 서로 주고 받는 패턴을 사용한다.

이처럼 DB래퍼 클래스를 통해 레코드를 조작하게 될 때, 세션빈이 생성한 Connection 객체를 DB 래퍼 클래스의 메소드에 콜할 때 인자로 함께 넘겨야한다.

세션빈이 Connection을 넘기지 않고 DB래퍼 클래스에게 Conenction을 핸들링하는 것을 맡길 경우, 5개의 DB래퍼 클래스 메소드를 호출하면 Connection 생성을 5번 하고, close() 명령을 통한 반환도 5번 일어나게 되는 셈이다. 다분히 비효율적이다.

이에 비해 DB래퍼가 자신을 호출한 클래스로부터 항상 Connection을 받아서 쓴다면 필요없는 자원낭비를 막을 수 있다.

이와 같은 원칙은 전체 시스템 구조에서 통일성 있게 적용돼야 할 것이다. 통일성 있게 적용되지 않으면 이런 원칙을 세우는 의미가 없다. 어떤 서브 패키지는 DB래퍼 클래스를 생성할 때 생성자에서 Connection을 받는다던가,
또는 아예 DB래퍼 클래스로 하여금 Connection을 관장하도록 한다던가 하면 전체 설계구조에 통일성이 없고 이를 바탕으로 한 추가 개발에 있어서도 비효율이 따르게 된다. 일관성 없는 구조의 클래스들을 재활용하는 신규 모듈도 역시 흐름에 일관성이 없을 것이다.

이제까지 언급했던 원칙을 패턴으로 사용하는 샘플소스를 보도록 하자.

아래 메소드는 사용자가 입력한 전표 내용으로 전표 등록을 하는 메소드이다. 이 세션빈 이름은 SlipManager이다.



전표를 등록하는 비즈니스 프로세스는 사용자가 입력한 전표정보를 받아서 마감여부를 체크한 후, 전표 번호 MAX 값을 알아내고 전표 TABLE에 INSERT 하는 작업으로 요약된다. 물론 실제 업무는 이보다 훨씬 더 복잡한 경우의 수를 가지고 있다. 법인카드사용정보가 있는 경우 법인카드 사용정보에도 등록을 시켜야 하고, 예산에서 지출되는 전표일 경우 예산 정보에도 그 내역을 기록해야 하는 등 다양한 업무 정의를 포함하고 있다.

소스를 보면 알겠지만 위에서 정한 원칙대로 Connectin 객체는 지역변수로 선언하여 사용하고 있으며, DB래퍼 클래스의 메소드에 Connection 객체를 넘기고 있다.

메소드 오버로딩(OVERLOADING)
이제 다른 시스템의 업무가 이 메소드를 사용해야 하는 업무 요구사항이 생길 경우에 대해 살펴보겠다. 인사시스템에 복리후생비 신청정보가 결재자의 승인을 받으면 자동으로 전표가 발행되어야 하는 요구사항이 나왔다 치자.

프로그램 설계자는 전표등록이라는 비즈니스 프로세스를 구현한 메소드가 SlipManager라는 세션빈에 이미 있다는 것을 알고 있으므로, 이 부분은 따로 전표 등록 메소드를 만들지 않고 기존 것을 재사용하기로 한다.

아래소스는 이처럼 위의 세션빈을 전표등록 메소드를 호출하는 복리후생비 신청정보 승인 프로세스를 보여주고 있다.

소스보기
 



위 소스를 보면 전표등록 메소드를 재사용 하고 있으나 한가지 우려되는 점이 있다. 바로 세션빈의 메소드를 콜 하는 것 까지는 문제가 없으나, 전표 등록 호출시 세션빈에게는 Connection 객체를 던지지 않으므로 호출되는 세션빈이 Connection을 따로 생성시켜 작업을 하고 있다.

위와 같은 업무에서는 세션빈의 메소드를 한번 호출하고 있지만 만약 사용자가 업무 복리후생비전표를 100장 생성시켜야 하는 경우라면 아래와 같은 for loop 문으로 콜 하게 될 것이다.

소스보기
 




결국 Connection은 100개가 생성되고, 100개가 반환되는 작업이 일어난다. 역시나 시스템 자원운용 면에서 보면 상당한 문제점을 야기시키는 부분일 것이다.

따라서 이와같이 타 세션빈에서 호출하는 메소드일 경우, DB 래퍼와 통신시에 Connection 객체를 넘겼듯 세션빈 메소드와 통신시에 Connection을 넘겨서 사용하는 패턴으로 가야 할 것이다.

위의 전표생성메소드를 Connection을 받아서 작업하는 메소드로 고쳐서 설계해보자. 물론 이 Connection을 생성시키고 닫아주는 주체는 전표생성 메소드를 콜한 세션빈이 하게 된다. 그렇다면 아래 소스처럼 regSlip 메소드를 오버로딩 한 메소드를 추가로 개발한다.

소스보기
 



이러한 메소드가 추가되면 먼저 만들어 두었던 regSlip 메소드는 아래와 같이 regSlip(Connection conn , SlipInfo[] sInfos)를 호출하자. 실제 비즈니스 프로세스는 regSlip(Connection conn , SlipInfo[] sInfos)안에 모두 있으므로, 이 메소드를 기존 그대로 놔두면 중복코드가 있게 된다.

소스보기
 




이와 같이 세션빈 메소드는 다른 세션빈 메소드가 업무상 호출할 수 있는 경우가 빈번하므로, 세션빈 메소드를 Connection 받는 것과 안 받는 것으로 오버로딩하는 패턴을 사용하게 된다.

세션빈 메소드는 다수 쿼리를 실행시키는 집합체
EJB 기반 프로젝트의 가장 큰 영역은 세션빈이다. 세션빈 내에서 모든 비즈니스 프로세스가 구현되므로, 세션빈 안에서 기타 클래스들을 어떠한 패턴으로 사용할 지 고민하며 설계하고 구현해야 재사용성이 높고 강력한 모듈을 만들 수 있다.

다음 강의에서는 실제 업무에서 일어나는 복잡한 프로세스를 구현함에 있어서 DBMS의 펑션이나 프로시져를 사용하는 것의 장점을 살펴보도록 하겠다.

2회까지는 세션빈 사용에 있어서의 클래스 패턴과, 시스템 성능 측면에서 어떤 점을 피해가야 하는지가 주된 논점이었다. 실제 프로젝트에서는 이 정도로 대부분의 이슈가 커버되겠지만, 막상 구현 결과물을 보면 세션빈 메소드가 수많은 쿼리를 실행시키는 집합체로 보인다.

그렇다면 이것을 단 한 번의 실행으로 끝내버리는 방법은 없을까. 다음 강의에서 그 방법에 대해 논의해보자. @  


http://www.zdnet.co.kr/techupdate/lectu ··· 2C00.htm
"Java" 카테고리의 다른 글
  • EJB 기반 프로젝트 수행 가이드 ④ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ③ (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ② (0)2007/05/18
  • EJB 기반 프로젝트 수행 가이드 ① (0)2007/05/18
  • MIDI Sound 생성하기 (0)2007/05/18
2007/05/18 11:22 2007/05/18 11:22
Posted by webdizen
Tags EJB, Java, 메소드 오버로딩, 세션빈, 컨테이너, 트랜잭션
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2993

Leave your greetings.

[로그인][오픈아이디란?]

Programming/STL2007/05/17 17:26

표준 템플릿 라이브러리(STL, Standard Template Library)를 왜 사용해야 하는가?

저자: 김승태 / 유진로보틱스 주임연구원

C++ 언어는 클래스, 멤버함수, 상속, 템플릿, 오버로딩 등의 언어적인 기술 외에 이들을 기반으로 필요하리라 예상되는 기능을 미리 만들어 둔 클래스, 함수 등의 집합체인 라이브러리를 제공한다. 그리고 이를 표준 라이브러리(Standard Library)라고 부른다. 이 표준 라이브러리에는 C 언어에서 널리 사용되던 도구가 들어있어 이를 이용해 C++에서도 입출력, 문자열 처리, 메모리 관리 등을 손쉽게 할 수 있다.

1980년 뱐 스트라우스트럽(Bjarne Stroustup)에 의해 탄생한 C++ 언어는 몇 번의 역사적인 큰 사건을 겪고 오늘날의 모습을 갖추게 되었다. 그 중 하나가 바로 1994년에 있었던 표준 템플릿 라이브러리의 도입이다. 이 변화는 알렉산더 스테파노프(Alexander Stepanov)가 주도하였다. 알렉스는 표준 라이브러리에 템플릿(Template)을 기반으로 한 클래스와 함수를 추가로 도입할 것을 제안하였고, 이 클래스와 함수를 “컨테이너(Container)”와 “알고리즘(Algorithm)”라 불렀다. 추가 요청을 한 클래스가 스택(Stack), 큐(Queue) 등의 데이터 구조이고, 함수는 대다수가 이 데이터 구조와 함께 연동해 작업을 수행하기 때문에 이 이름을 선택한 것이다.

템플릿 기반의 클래스와 함수는 미국 표준 위원회(ANSI, America National Standard Institute)에서 제정하는 C++ 표준에서 1995년에 처음으로 표준 템플릿 라이브러리(STL, Standard Template Library)라는 이름으로 만장일치로 도입되었고, 이후 국제 표준화 기구가 제정하는 C++ 언어에서 표준 라이브러리와 완전히 흡수되면서 표준 라이브러리로 통합되었다. 그리고 표준은 기술 보고서 TR1(Technical Report)에 있는 내용을 중심으로 표준 라이브러리를 계속 확장하고 있다.

표준 템플릿 라이브러리가 표준 라이브러리로 통합되어 이제 표준 템플릿 라이브러리라는 명칭을 사용하는 것은 어쩌면 역사적인 사건을 가리킬 때나 사용해야 올바른 것일지도 모른다. 그러나 현재도 표준 템플릿 라이브러리를 처음 구현했던 HP의 STL을 계승한 SGI에서도 여전히 표준 템플릿 라이브러리라는 용어를 사용하고 있으며, 많은 국제 C++ 언어 전문가들 역시 표준 템플릿 라이브러리라는 용어를 사용하고 있다. 비록 C++ 언어의 국제 표준(IS, International Standard)인 14882에서는 공식적인 언급이 전혀 없지만.

표준 템플릿 라이브러리는 컨테이너(Container), 알고리즘(Algorithm), 이터레이터(Iterator), 그리고 함수 개체(Functor, Function Object)로 크게 구성되어 있다. 이들에 대해 각각 살펴보자.

• 컨테이너
같은 타입의 원소를 관리하는 선형적인 데이터 구조를 지원하는 클래스로, 일종의 지능화된 동적 배열이다. 원소를 추가하거나 삭제할 수 있고, 크기 변경에 따라 내부에서 메모리를 관리해서 개발자가 메모리를 직접 관리하는 부담을 줄여준다. 컨테이너에는 크게 시퀀스 컨테이너 계열(Sequence Container)과 연관 컨테이너 계열(Associated Container)이 있는데, 시퀀스 컨테이너 계열은 원소를 스택, 큐, 리스트 등의 데이터 구조에 담아 관리하고, 연관 컨테이너 계열은 균등 트리(Balanced Tree)에 담아 원소를 관리한다. 이 외에도 현재 표준화가 진행 중인 C++03(ISO/IEC 14882:2003의 약칭)의 차기 버전인 C++0x에서는 해시 기반의 연관컨테이너(Hashed Associated Containers)가 새롭게 추가될 것으로 기대된다.

• 알고리즘
이터레이터를 통해 시퀀스 컨테이너에 일정한 구간에 정하고, 이에 대해 복사, 전환, 병합, 정렬 등의 연산을 지원한다. 이들은 크게 입력된 이터레이터가 가리키는 곳에 변화를 주는 변형 알고리즘과 변화를 주지 않는 불변형 알고리즘, 정렬에 관련된 정렬 알고리즘으로 분류된다. 변형 알고리즘에는 구간 내 원소의 순서를 뒤 섞는 random_shuffle, 조건에 맞는 원소를 교체하는 replace, 구간 내 원소를 모두 같은 값으로 바꾸는 fill, 구간 내 원소를 주어진 함수가 반환하는 값으로 바꾸는 generate, 조건에 맞는 원소를 제거하는 remove, 동일한 값을 가지는 원소를 제거하는 unique 등이 있다. 불변형 알고리즘에는 주어진 구간에 있는 모든 원소에 접근하여 for 문의 역할을 할 수 있도록하는 for_each, 두 시퀀스를 비교하여 다른 곳이 있는지를 찾는 mismatch, 두 시퀀스가 같은 값을 가진 원소들인지를 확인하는 equal 등이 있다. 정렬 알고리즘에는 구간 내 원소를 정렬하는 sort와 안정적인 조건을 추가로 하는 stable_sort가 대표적이고, 상위 n개만 정렬하는 nth_element, 주어진 값을 갖는 최초 원소를 찾는 lower_bound, 마지막 원소 바로 다음을 찾는 upper_bound, 주어진 값을 갖는 구간을 가리키는 이터레이터를 반환하는 equal_range, 두 시퀀스를 합치는 merge, 집합 연산을 제공하는 set_union, set_intersection, set_diiference 등이 있다.

• 이터레이터
원소를 관리하는 방법을 제공하는 컨테이너의 위상에 걸맞게 포인터의 개념을 한층 일반화시킨 지능화된 포인터다. 이터레이터는 내부적으로 실제 포인터를 관리하는 클래스며, 포인터를 이용해 다양한 형태의 데이터 구조를 일관된 방법으로 원소에 접근할 수 있는 방법을 제공한다. 이터레이터에서는 포인터를 사용하는 데 쓰는 연산자인 *, ->, ++, -- 등을 이터레이터에 맞게 오버로딩하였기 때문에 일반의 포인터와 같은 방식으로 사용할 수 있다. 즉, 사용 목적에 따라 입력용 InputIterator, 출력용 OutputIterator, 입출력용 ForwardIterator, 양방향 BidirectionalIterator, 임의 접근용 RandomAccessIterator 등으로 기능을 세분화하여 그 이름으로부터 손쉽게 이터레이터의 역할을 이해할 수 있도록 하고, 기능을 제한함으로써 잠재적으로 날 포인터(Raw Pointer)를 무분별하게 사용하기 때문에 발생할 수 있는 에러의 가능성을 원척적으로 봉쇄하는 역할을 한다.

• 함수 개체
함수개체는 연산자 ( )를 오버로딩한 클래스로, 컨테이너, 알고리즘 등에서 비교를 위해 연산자 <를 대체하는 등의 지능화된 함수 역할을 한다. 표준 라이브러리에서는 많이 쓰는 기능을 중심으로 함수 개체를 미리 정의하여 제공하고 있다. 이들은 크게 산술 계산용으로 사용되는 plus, minus, multiplies, divides, modulus, negate, 비교 연산에 사용되는 equal_to, not_equal_to, greater, less, greater_equal, less_equal, 논리 연산에 사용되는 logical_end, logical_or, logical_not으로 구분된다. 그러나 함수 개체 자체가 함수형 프로그래밍의 기본적인 도구가 되지만, 표준 템플릿 라이브러리가 완전한 함수형 패러다임을 하는 것은 아니다.

• C++ STL 실전 프로그래밍
표준 템플릿 라이브러리에는 기존의 라이브러리와 달리 몇 가지 큰 장점이 있다. 스택, 리스트, 큐, 균등 트리 등의 데이터 구조에 대한 직관적인 인터페이스를 제공해 사용자가 손쉽게 사용할 수 있다. 또한 정렬, 이진 탐색, 찾기, 병합(Merge), 최대 원소 관리, 상위 n개의 원소 검색 등의 고급 알고리즘도 제공한다. 이런 고급 연산 기능은 기존 라이브러리에서 제공하는 저수준 기능과는 크게 달라진 점이다. 그리고 이 기능은 예외 처리를 기반으로 제공된다. 예를 들어 컨테이너에 저장되어 있는 어떤 원소에 대해 접근하기 위해 사용되는 함수 at은 지정된 매개변수가 접근할 수 있는 범위를 넘어설 경우 예외 out_out_range를 던진다. 이와 같이 많은 에러가 발생하는 상황에 대해 예외를 정의해 놓아 프로그램이 언제나 제어가 가능한 안전한 상태에 놓일 수 있도록 해 주고 있다. 포인터를 이용한 배열형 메모리의 관리에서 매번 직접 인자를 검사해야 하는 것과는 큰 차이가 있다.

표준 템플릿 라이브러리의 가장 큰 매력은 더 이상 포인터를 관리하지 않아도 된다는 데 있다. 고급 컨테이너와 알고리즘, 그리고 이터레이터가 제공하는 프로그래밍 구조는 포인터가 필요한 대부분의 경우를 대체할 수 있도록 해 주고, 더불어 높은 수준의 에러 처리 구조와 지능적인 연산에 의해 포인터를 직접 사용할 때보다 훨씬 더 안전하고, 효율적으로 데이터를 관리할 수 있도록 도와준다.

두 번째로 표준 템플릿 라이브러리는 제네릭 프로그래밍(Generic Programming)을 기반으로 이루어져 있다. 즉, 템플릿을 기반으로 제공되는 클래스와 함수들은 이들 내부에서 사용하고 있는 각 타입들을 많은 경우 템플릿 매개변수화하여 제공하고 있고, 이에 따라 실행 시간에 비용을 지불하지 않는 높은 효율성을 지닌 프로그램의 일반화가 가능하도록 해 준다.

또한, 표준 템플릿 라이브러리는 표준의 일부이기 때문에 g++, 비주얼 C++ 등의 특정한 번역 환경을 가정하지 않아 이를 기반으로 작성된 프로그램이 어느 곳에서나 동일하게 번역되고, 실행되는 것이 보장된다. 즉 작성된 프로그램의 이동성(Portability)이 최대한 보장되는 것이다.

이러한 매력에도 불구하고 많은 C++ 언어 사용자들이 표준 템플릿 라이브러리의 사용을 꺼려하고 있다. 표준 템플릿 라이브러리라고 하면 어려운 전문가의 도구, 혹은 뭔가(?) 특별한 목적으로 사용하는 것으로 생각하는 경우가 많기 때문이다. 하지만 지금까지 말해왔듯 그렇지 않다. 스택, 리스트, 트리 등의 데이터 관리와 정렬, 합병, 제일 큰 원소 찾기 등의 기능은 아주 일반적인 것이다. 많은 프로그램에서 이를 직접 구현해 사용하고 있을 것이다. 표준 템플릿 라이브러리는 바로 이런 일을 대신하는 것을 목적으로 만들어졌다. 대단한 무언가가 절대 아니다. 사용자는 단지 자신이 사용할 컨테이너와 알고리즘을 필요에 따라 선택하고, 사용하기만 하면 되는 것이다.

템플릿(Template)이라는 이름 때문에 쉽게 범접할 수 없는 어려움이 느껴지지만 템플릿의 기본 기술을 사용할 수 있는 정도만 파악한다면 표준 템플릿 라이브러리를 사용하는 것은 그다지 어렵지 않다. 오히려 사실 이제 막 C++ 언어를 배우려는 개발자는 표준 라이브러리를 사용하는 것부터 시작하는 편이 좋다. 표준 라이브러리는 직관성이 높은 라이브러리인 동시에 높은 수준의 연산을 지원해 주기 때문이다. 그래서 C++ 언어 문법의 가장 기초적인 것만 파악하고 있어도 표준 라이브러리를 사용하여 프로그램을 작성하는 데는 전혀 문제가 없다. 오히려 반드시 해야 할 에러 처리 등을 생각하면 이를 직접 수행하는 것보다 표준 라이브러리의 에러처리에 의존하는 것이 훨씬 더 이득이 된다. 그렇기 때문에 많은 전문가들이 표준 라이브러리를 사용하는 것에서부터 C++ 언어를 시작하기를 추천한다.

이 외에도 작업 환경에 대한 지원 때문에 표준 템플릿 라이브러리의 사용을 꺼려하기도 한다. 가장 일반적인 환경이 비주얼 C++, g++ 등일 텐데, 표준 템플릿 라이브러리 자체가 길어야 10여년 전에 탄생되었던 점을 감안하면 이들 환경에서 표준 템플릿 라이브러리를 제대로 지원하기 시작한 것은 그다지 오래된 일이 아니다. 그래서 애써 표준 템플릿 라이브러리를 배워 프로그램에 적용하더라도 번역이 안되거나 거의 암호화된 수준의 에러 메시지를 만나 당황했을 것이다. 하지만 비주얼 C++ 6.0 버전 이상, .NET, g++3.3 버전 등의 비교적 최신 컴파일러에서는 이제 표준 템플릿 라이브러리를 거의 완벽하게 지원하고 있다. 아직 세부 구현에 실수가 있긴 하지만 대다수의 실제적인 적용에 있어 심각한 문제를 초래하는 경우는 거의 없다. 또한 STLFilt 등의 널리 알려진 무료 진단 도구는 복잡한 에러 메시지를 간단한 형태로 바꾸어 에러 메시지의 내용을 쉽게 이해할 수 있는 형태로 바꿔주므로 이런 도구를 적극적으로 이용하는 것도 좋다.

뜻밖에도 개발자 중에는 왜 표준 템플릿 라이브러리를 사용하지 않는가에 대한 대답으로 “MFC를 사용하는데 또 STL을 사용해야 할 이유가 있는가?”라고 반문하는 경우가 많았다. 그런데 이는 표준 템플릿 라이브러리에 대한 잘못된 이해로 생기는 의문이다. 표준 템플릿 라이브러리는 MFC(Microsoft Class Library)와 아무 관계가 없다. 아니, MFC와 표준 템플릿 라이브러리를 함께 사용해야 더 강력한 프로그램을 작성할 수 있다. MFC와 표준 템플릿 라이브러리가 추구하는 목적이 근본부터 다르다. 표준 템플릿 라이브러리는 컨테이너, 알고리즘 등 데이터 구조와 관련된 인터페이스를 플랫폼 독립적인 방법으로 제공하는 것이 주목적이지만, MFC는 GUI(Graphics User Interface)를 윈도우라는 실행 환경에서 쉽게 프로그램화할 수 있도록 하는 것이 주목적이어서 서로 겹치는 부분이 거의 없다. 더구나 이들을 구성하는 패러다임 역시 전자는 명령형, 제네릭, 함수형 패러다임을 섞어 쓴 반면, 후자는 개체지향적이다. 물론 비슷한 목적의 요소가 다소 있기는 하다. 문자열을 관리하는 CString과 표준 라이브러리의 string, 리스트를 구현한 CObList와 표준 라이브러리의 list 등이 그것이다. 하지만 적어도 필자의 경험으로는 표준 라이브러리가 MFC 라이브러리보다 훨씬 나은 방법을 제공하고 있으며, 아마 표준 라이브러리를 사용한다면 여러분도 나와 같은 경험을 하게 될 것이다.

표준 템플릿 라이브러리를 아직 사용하지 않는 C++ 프로그래머라면 지금부터 접해보라고 자신있게 말할 수 있다. 먼저 시퀀스 컨테이너의 일종인 vector를 malloc으로 관리하는 동적 배열을 대체하는 것으로부터 시작해 보라. 전혀 새로운 C++ 세계를 경험할 것이다.


http://network.hanbitbook.co.kr/view.php?bi_id=984
"STL" 카테고리의 다른 글
  • A beginner's tutorial on STL (0)2007/07/17
  • 표준 템플릿 라이브러리(STL, Standard Template L... (0)2007/05/17
  • 함수대신 function object를 대입하자 (0)2007/03/23
  • 정렬과 탐색 루틴이 필요하신 분 (0)2007/03/23
2007/05/17 17:26 2007/05/17 17:26
Posted by webdizen
Tags Algorithm, C++Keyword C++, Container, Functor, Iterator, STL, 알고리즘, 이터레이터, 컨테이너, 함수 개체
No Trackback No Comment

Trackback URL : http://www.webdizen.net/blog/trackback/2981

Leave your greetings.

[로그인][오픈아이디란?]

«Prev  1  Next»

RSS HanRSS
Blog Image
webdizen
이곳은 컴퓨터에 대해 연구하고, 공유하고, 소통하기 위한 연구실입니다. 개인적으로는 OLAP, Data Mining, Semantic Web, Data Modeling에 대해서 연구하고 있습니다.

Categories

전체 (3009)
Webdizen (141)
Life (6)
Diary (16)
Blog (9)
IDEA (2)
Travel (10)
Book (16)
Photo (7)
Movie (8)
Music (14)
Leisure Sports (10)
Funny (6)
Hardware (121)
Software (120)
Windows (5)
Unix & Linux (120)
Installation (5)
Kernel (10)
System (34)
Develop (22)
X-Window (0)
Applicaton (31)
Security (4)
Framework (2)
Hadoop (2)
Programming (804)
Algorithm & Data Structure (1)
Assembly (38)
UNIX/Linux C (95)
C++ (128)
STL (4)
Java (38)
Win32 API (92)
ATL/COM (44)
MFC (151)
.NET (26)
WCF/WPF (4)
C# (28)
Network Programming (17)
Database Programming (12)
OpenGL / DirectX (13)
Multimedia Programming (0)
Game Programming (21)
Parallel Distributed Progra... (0)
Reverse Engineering (0)
Debugging (9)
Python (1)
Ruby (1)
Ruby on Rails (1)
QT (4)
GTK (0)
JSP (0)
PHP (6)
ASP.NET (6)
ASP (2)
Development (28)
Useful Library (2)
Data Modeling (0)
Database (105)
Oracle (4)
MSSQL (41)
MySQL (2)
Data Warehouse (2)
Data Mining (4)
Network (66)
Web (79)
DHTML (4)
XHTML (1)
Javascript (1)
CSS (1)
AJAX (9)
XML (11)
Flex (1)
Silverlight (3)
Security (91)
DoS (1)
Kernel (10)
Scanning (3)
Sniffing (0)
Spoofing (4)
Overflow (28)
Web (11)
Shell (10)
Format String (14)
Window (2)
Embedded (70)
Multimedia (27)
Mobile (14)
Graphic (24)
Management (633)
Knowledge (581)
Hadoop (0)

Notice

  • 메타 블로그 사이트에 등록
  • 새해 맞이 블로그의 변화
  • 블로그 명칭 변경
  • 도메인(www.webdizen.net) 구...
  • TEXTCUBE 1.6.1로 업그레이드...

Tags

  • Misc
  • 데이터 정렬
  • 클립아트
  • 예지원
  • Linux
  • 인맥
  • mapping
  • RC헬기
  • MFC
  • 한/영 전환
  • 영어
  • IPC
  • w3m
  • XHTML
  • 대용량 파일
  • Django
  • 대회
  • HyperBac
  • RAISERROR
  • 나눔고딕 코딩

Recent Articles

  • 트위터(Twitter)의 시작!.
  • 청년 리더의 조건.
  • 애플의 타블렛 PC - 아이패드....
  • 미래의 인터페이스 - 육감 기....
  • 기초발성법 동영상 강좌.

Recent Comments

  • 학교 과제물중 쓰레드에 대하....
    장진혁 03/17
  • 관리자만 볼 수 있는 댓글입....
    비밀방문자 03/12
  • 상대방의 이야기를 열심히 경....
    DoNuts 03/03
  • Lots of students know techn....
    Bobbi35Shannon 02/25
  • 좋은글 잘 보고 갑니다..
    Und_hacker 01/08

Recent Trackbacks

  • printf,scanf를 이용한 형식....
    yundream의 프로그래밍 이야기 03/10
  • 파일 열기/저장하기 CFileDialog.
    은마군의 나태블록 2009
  • World IT Show 2008.
    상우 :: Oranzie's BLOG 2008
  • cvs서버 설치하기.
    3인3색 2008
  • 속속 공개되는 Google Chart....
    PHP와 Web 2.0 2007

Archive

  • 2010/02 (1)
  • 2010/01 (6)
  • 2009/12 (5)
  • 2009/09 (3)
  • 2009/08 (1)

Calendar

«   2010/03   »
일 월 화 수 목 금 토
  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 31      

Bookmarks

    • Administration
      • IIS.NET
      • NTFAQ
      • OS의 모든 것
      • 리눅스포털
    • Database
      • SQL Server Central
      • SQL Team
    • Development
      • .NET Heaven
      • ASP Alliance
      • ASP.NET 2.0
      • Bullog.net
      • C# Corner
      • C++ (C PlusPlus.com)
      • C++ Reference
      • CodeGuru
      • CodePlex
      • DebugLab
      • Dev Articles
      • Devpia
      • DotNet Junkies
      • DotNet Zone
      • Driver Online
      • GOSU.NET
      • HOONS 닷넷
      • Joinc 팀블로그
      • KOSR
      • MSDN Home Page
      • OSR Online
      • Sky.ph - 개발자 커뮤니...
      • TAEYO.NET
      • The Code Project
      • WindowsClient.net
      • 김상욱의 개발자 Side
      • 조인시 위키
    • Human Networks
      • belief21c's e-space
      • I think I can
      • Invisible Rover's Blog :D
      • Rodman®
      • ■ Feel So Good~! ■
      • 까만 나비
      • 나를 가꾸는 시간.
      • 나만의 즐거움~~!
      • 단녕
      • 상우 :: Oranzie's BLOG
    • Information Technology
      • Microsoft TechNet
      • 지디넷코리아 - 글로벌...
    • Security
      • FoundStone
      • milw0rm
      • NewOrder
      • OpenRCE
      • Phrack.org
      • Reverse Engineering b1...
      • Reverse Engineering Team
      • RootKit
      • SecurityFocus
      • SecurityXploded by Nag...
      • Wow Hacker
      • Zone-H
Textcube
Louice Studio Inc.
Powered by Textcube. Original designed by Tistory.