2010. 8. 20. 17:38 IT 자료/경영정보시스템
'분류 전체보기'에 해당되는 글 38건
- 2010.08.20 [펌] SOA (출처: 자바서비스넷)
- 2010.02.22 가상화
- 2008.08.03 AOP (Aspect Oriented Programming)
- 2008.08.03 AOP (Aspect Oriented Programming)
- 2008.08.03 [자료구조] M-one 탐색 Tree, B-Tree, B*-Tree, B+-Tree, TRIE
- 2007.09.27 [UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」
- 2007.09.27 [UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드
- 2007.09.27 [UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링
- 2007.09.27 [UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML
- 2007.09.27 [UML 제대로 알기] ① 가능성·확장성 품고 등장한 UML 2.0 1
2010. 2. 22. 18:54 IT 자료/최신기술
가상화
2008. 8. 3. 04:52 IT 자료/소프트웨어 공학
AOP (Aspect Oriented Programming)
AOP는 구조적 방법론에서 객체지향 방법론으로 전환처럼 시스템 개발에 관한 전체적인 변화는 아니다. Object-Oriented Programming이 Aspect-Oriented Programming으로 대체되는 일은 없을 것이다. AOP는 구조적 방법론에도 적용될 수 있고, 다른 방법론에도 다 적용될 수 있지만, 주로 객체지향방법론이 가지는 단점을 보완하는 것으로 묘사되고 있다. 그러면 객체지향 프로그래밍이 또는 다른 이전의 프로그래밍 기법들이 Cross-cutting Concern를 어떻게 다루는지 알아보자. 매우 간단하다. Primary Concern를 구현한 프로그램에 함께 포함시켰다. 그것이 단 한 줄의 메소드 호출이라 하더라도. 많은 프로그래머들은 거의 모든 프로그램에 산재된 로그하는 단 한 줄의 코드를 찾아서 바꾸어 본 경험이 있을 것이다. 또는 간단하게 생각하고 프로그램을 수정하려고 했는데, 도데체 어디를 수정해야 되는지 모르게 코드가 길고, 알 수 없는 코드들이 자리를 차지하고 있을 때의 난감함. Primary concern, Cross-cutting concern이 하나의 프로그램 안에 들어가게 되면, 프로그램을 이해하기가 힘들고, Cross-cutting concern 코드가 여기저기에 산재되어 수정하기 힘들게 된다. 당연히 생산성 떨어지고, 품질 떨어지고, 유지보수 비용 많이 들게 된다.
그럼 AOP는 Cross-cutting concern를 어떻게 처리하는가? 이것도 매우 간단하다. 새로운 아이디어라고 할 수도 없다. Primary Concern 구현하는 코드 따로, Cross-cutting concern 구현하는 코드 따로 쓰고, 나중에 두 개 조합하게 완벽한 어플리케이션 만들겠다는 것이다. 기술 용어로 쓰면, Advice(Cross-cutting concern 구현한 코드)와 Primary concern 구현한 코드를 Point-cut 정보를 이용해서 Weaving(조합)하는 것이 AOP가 이 문제를 다루는 방법이다.

기술적 용어로서의 "Aspect"은 "Advice"와 "Point-cut"을 함께 지칭하는 단어이다. Point-cut은 어떤 Advice를 Code 어느 위치에 둘 것인가 하는 것이다. 예를 들면, 로그 기능을 구현한 Advice는 Code 속에 있는 모든 public 메소드가 수행되고 나면, 그 마지막에 실행되어라 라고 지정한 것이라 할 수 있다.
이전까지의 객체지향 프로그래밍은 Cross-cutting concern을 정적으로 어플리케이션에 결합시킨 반면 AOP는 동적으로 Cross-cutting concern를 다룬다고 표현하기도 합니다. 용어에서도 알 수 있듯이 AOP는 소프트웨어 엔지니어링 원칙 중에 하나인 "Separation of concern"를 구현하려고 하고 있습니다. 이러한 문제들을 다루고 있는 분야 중에 하나는 디자인 패턴할 수 있고, 예를 들어, Visitor 패턴은 정적인 구조를 동적으로 바꾸려고 합니다. AOP가 현재까지 나온 방법들 중에서 Cross-cutting concern를 다루는 가장 좋은 방법인가 하는 질문엔 아직 답하긴 힘들 것 같습니다. 그럼에도 분명 언제가는 책상 위에 관련 서적 한 권 있어야 할 것 같은 분야가 될 것 같습니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
AOP (Aspect Oriented Programming) (0) | 2008.08.03 |
---|---|
[UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」 (0) | 2007.09.27 |
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드 (0) | 2007.09.27 |
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
2008. 8. 3. 04:51 IT 자료/소프트웨어 공학
AOP (Aspect Oriented Programming)
객체지향을 넘어 관점지향으로 AOP 이일민 (DevelopGate 기술 컨설턴트) 2006/05/01 |
전 세계 자바 EE 개발 프로젝트의 80%가 원래 계획했던 목표를 다 이루지 못하고 실패로 끝나고 만다는 사실은 한편으로는 충격적이지만 어쩌면 당연한 결과라고 받아들여지고 있다. 개발자들은 좀 더 단순한 방법을 찾아야하고 그에 따라 더욱 효과적으로 명확한 결과를 얻어낼 수 있어야 한다. 소프트웨어 개발의 단순함의 핵심에 바로 관점지향 프로그래밍, AOP가 존재한다.
최근 몇 년 간 자바 개발자들이 경험하고 있는 새로운 기술의 흐름과 방향을 한마디로 말해보자면‘단순함(simplicity)의 추구’라고 할 수 있다. 아무리 정교하고 잘 설계된 프로그래밍 기술과 개발 방법론, 분석설계 기술을 사용한다고 하더라도 개발자들이 이해하고 구현해야 하는 애플리케이션의 구조와 구현 내용은 갈수록 복잡하고 다차원적이 되어가고 이를 감당하기 위해서 개발자들은 점점 복잡한 미로 속으로 빠져들어 갈 수밖에 없다.
관점지향 프로그래밍(Aspect Oriented Programming, 이하 AOP)이라는 말을 처음 들어보면 객체지향 프로그래밍(Object Oriented Programming, 이하 OOP)이 떠오른다. AOP는 결국 OOP의 뒤를 잇는 또 하나의 프로그래밍 언어 구조라고 생각될 수 있다. 지금까지 프로그래밍 기술은 기계어와 같은 초기 언어를 기반으로 한 프로그래밍으로부터 출발해서 절차적 프로그래밍을 거쳐 OOP에 이르렀다. 20여년 이상 현장에서의 적용과 내부적인 개념의 발전 그리고 자바나 C# 같은 대중적인 언어의 등장에 힘입어 이제는 OOP가 전체 소프트웨어 개발의 대표적인 패러다임으로 자리 잡고 있다.
그럼 이제 AOP의 등장으로 OOP는 사라져 갈 것이고, AOP가 OOP를 대체하게 될 것이라고 할 수 있을까? 결코 그렇지 않다. AOP와 관련된 가장 중요한 개념은‘AOP는 결코 OOP의 자리를 대신하기 위해서 등장한 기술이 아니다’라는 것이다. 오히려 AOP는 OOP를 더욱 OOP답게 만들어줄 수 있다고 할 수 있다. 많은 AOP 기술의 주도자들과 개발자들은 AOP가 OOP를 사라지게 하는 것이 아니라 더욱 완전하게 만들어 줄 수 있다고 주장한다. 또 AOP는 OOP뿐만 아니라 기존의 절차적 프로그래밍에도 적용되어질 수도 있다. 결국 AOP는 지금까지의 프로그래밍 기술 변화의 흐름에 다른 차원의 관점을 제시함으로써 새로운 프로그래밍 패러다임을 이끌어내고 있다고 볼 수 있다.
AOP의 필요성
AOP의 필요성을 이해하는 가장 기초가 되는 개념은‘관심의 분리(Separation of Concerns)’이다. 관심의 분리는 컴퓨터 프로그래밍의 가장 기초가 되는 원리 중 하나이다. 거의 모든 프로그래밍 패러다임은 바로 이 관심의 분리 과정을 통해 문제 영역(problem domain)을 독립적인 모듈로 분해한다. 절차적 프로그래밍에서는 분리된 관심을 프로시저로 구성하고 OOP에서는 이를 클래스로 작성한다. 여기서 AOP는 OOP를 적용한다고 할지라도 충분히 분리해 낼 수 없는 부분이 있다는 문제 제기에서 출발한다.
AOP에서 주목하고 있는 부분은 OOP와 같은 모듈화가 뛰어난 방법을 사용하더라도 결코 쉽게 분리된 모듈로 작성하기 힘든 요구사항이 실제 애플리케이션 설계와 개발에서 자주 발견된다는 점이다. AOP에서는 이를 횡단 관심(crosscutting concerns)이라고 한다. 이에 대비해서 해당 시스템의 핵심 가치와 목적이 그대로 드러난 관심 영역을 핵심 관심(core concerns)이라고 부른다. 이 핵심 관심은 기존의 객체지향 분석/설계(OOAD)를 통해 쉽게 모듈화와 추상화가 가능하다. 하지만 횡단 관심은 객체지향의 기본 원칙을 지키면서 이를 분리해서 모듈화하는 것이 매우 어렵다.
이는 횡단 관심의 특징을 모듈로 구현하는 것이 어렵기 때문이 아니다. 문제는 그 구현된 모듈이 다른 핵심 관심을 구현한 모듈과 매우 긴밀하게 결합되어 있기 때문이다. 심지어는 어떤 시스템 영역의 모든 모듈과 연동되어야 하는 경우마저 있다. 그래서 기존의 핵심 관심을 구현한 모듈과 달리 횡단 관심은 그 구현 시점에서 그 분리가 쉽지가 않다. 기존의 OOP 언어와 기술로는 뾰족한 답이 안 나오는 것이다.
대부분의 엔터프라이즈급 애플리케이션은 로그작성(logging)과 보안/인증(security/authentication), 트랜잭션(transaction), 리소스 풀링(resource pooling), 에러 검사(error checking), 정책 적용(policy enforcement), 멀티쓰레드 안전관리(multithread safety), 데이터 퍼시스턴스(data persistence) 등의 적용이 필요하다. 이러한 관심들은 애플리케이션의 핵심 관심과 다른 형태로 존재한다.
예를 들어 은행 업무를 처리하는 시스템을 생각해보면 핵심 관심은 예금입출금, 계좌간이체, 이자계산, 대출처리 등으로 구분할 수 있다. 이는 전체 애플리케이션의 핵심요구사항과 기능들을 구분해서 모듈화할 수 있고 OOP에서라면 클래스와 컴포넌트 형태로 구성이 가능하다. 각각 모듈화된 클래스들은 추상화 등의 작업을 통해 서로 느슨한 연결 상태(loosely coupled)로 만들어서 일부 모듈을 타 시스템에서 재활용할 수 있고, 또 구현의 확장이나 교환도 쉽게 가능하다. 객체지향 기술이 우리에게 준 비전이 바로 이러한 코드의 모듈화와 추상화를 통해 간결하고 깔끔한 코드 작성이 가능하고 재활용성을 뛰어나게 해주는 것이다.
![]() |
<그림 1> 프로그래밍 패러다임의 변화 |
하지만 현실은 그렇지 못하다. 실제로 개발되어 돌아가는 은행 업무의 각 모듈에는 사실 해당 업무를 처리하기 위한 내용만 존재해서는 불완전할 수밖에 없다. 일단 각 업무를 처리하는 클래스와 구현된 메쏘드에는 향후 시스템을 분석하거나 추적을 위해 로그를 작성하는 기능이 필요하다. 또 인증 받은 사용자가 접근하는지를 체크하고 권한 여부를 따지는 보안 기능이 필요하다. 거기다 내부에서 사용하는 퍼시스턴스 처리를 위해 트랜잭션을 시작하고, 또 필요에 따라서 그것을 커밋 또는 롤백하는 부분도 들어가야 한다. 예외 상황이나 문제가 발생했을 때는 그것을 기록에 남기는 부분도 있어야 하고, 필요하면 관리자에게 이메일을 발송해야 한다. 어떤 경우는 특정 업무를 사용하는 사용자의 패턴을 분석하기 위해 통계처리를 위한 기능도 포함 돼야 한다.
이러한 부가적인 기능들은 각각 구현을 독립적인 클래스로 작성될수 있지만 그렇게 구현된 기능들을 호출하고 사용하는 코드들이 핵심 모듈 안에 필요한 영역에 모두 포함될 수밖에 없다. AOP를 적용하지않은 OOP에 의해서만 작성된 간단한 계좌이체 처리를 위한 클래스의 구성을 살펴보자.
로깅, 인증, 권한체크, DB 연동, 트랜잭션, 락킹, 에러처리 등의 기능을 아무리 뛰어난 OOP 기술을 이용해 모듈로 구성하고 추상화를 통해 최대한 독립시킨다고 해도 <리스트 1>에서 보듯이 핵심 모듈의 모든 클래스와 메쏘드 속에 이와 연동되는 부분이 매우 깊이 그리고 상당한 양을 갖으면서 자리 잡고 있다. 실전에서 사용되는 핵심 모듈 클래스들은 이보다 더 복잡하면 복잡했지 더 단순하지는 않을 것이다. 이 코드에서 핵심기능을 담당하고 이 클래스가 설계된 바탕의 핵심 관심을 구현하는 코드는 단 다섯줄에 불과하다. 하지만 그 외의 부가적인 코드를 포함하지 않으면 엔터프라이즈급 애플리케이션으로는 쓸모없을 수밖에 없다.
![]() |
<그림 2> 횡단 관심 |
이러한 횡단 관심을 구현하고 또 그 모듈과 연동이 되는 코드들이 거의 모든 핵심 모듈에 다양한 형태로 존재할 수밖에 없다. 실제로 모듈화가 잘 된 애플리케이션 클래스를 보더라도 핵심기능을 위한 코드보다 이런 저런 부가적인 기능과 처리를 위한 부분의 양이 더 많아지그런데 만약 이렇게 개발된 클래스가 한 수천 개가 되고 대부분이 앞의 코드와 갈이 작성됐다고 했을 때 어느 날 새로운 은행 캠페인이 시작되어서 각 메쏘드에서 사용되는 계좌정보에서 내용을 뽑아내어 통계처리를 하도록 새로운 요구사항이 생겼다면 어떻게 해야 하겠는가?
그와 관련된 모든 클래스들을 찾아 <리스트 1>과 같은 코드 틀 안에 또 새로운 통계처리용 코드를 삽입하는 수밖에 없다. 또 만약 다른 종류의 로깅플랫폼을 사용해 로그처리하는 클래스와 메쏘드가 달라지고 로그 메시지가 변경이 되었다면? 또 개발자들은 모든 클래스 안에 있는 로그관련 코드를 일일이 다 수정해 주는 수밖에 없다. 그러다가 만약 중요한 클래스에서 한두 군데 로그기록 코드가 빠졌고 이로 인해 결과를 확인하는데 문제가 생겼다면? 이를 다시 확인하고 찾아내는 일만 해도 엄청난 작업이 아닐 수 없을 것이다.는 것이 현실이다.
더 나아가서 이렇게 OOAD와 OOP를 이용해 개발한 시스템의 일부 모듈을 타 은행에서 재활용하고 싶다고 생각해보자. 과연 이것이 가능한가? 아마 매우 어려울 것이다. 객체지향 기술이 코드의 재활용성을 높여줄 수 있다는 것은 이론적으로는 맞는 일이지만 현실적으로는 복잡하게 섞여있는 횡단 관심 코드로 인해 이 부분을 다 수정하기전에는 다른 환경에서 같은 핵심기능을 처리하는 코드를 사용한다는 것은 불가능하다. AOP가 적용되지 않은 방식의 프로그램 코드에서 보면 핵심 관심 모듈에서 횡단 관심 모듈을 찾고 사용하는 구조로 작성되어있다. 이렇게 작성된 애플리케이션은 몇 가지 심각한 문제를 가지고 있다.
◆ 중복되는 코드 : 복사&붙이기에 의해 만들어진 여러 모듈에서 중복되는 코드의 문제점은 이미 잘 알려져 있다. 하지만 AOP를 사용하지 않은 대부분의 애플리케이션에서는 어떠한 추상화와 리팩토링을 통해서도 반복되는 코드를 피하기가 어렵다.
◆ 지저분한 코드 : 횡단 관심과 관련된 코드들이 핵심기능 코드 사이사이에 끼어들어가 있기 때문에 코드가 지저분해지고 이에 따라 가독성이 떨어지며 개발자들의 실수나 버그를 유발하고 후에 코드를 유지보수하는데 큰 어려움을 준다.
◆ 생산성의 저하 : 문제영역에 대한 지식과 분석을 토대로 이를 구현해야 하는데 충실해야 하는 애플리케이션 개발자들이 자주 등장하는 횡단 관심을 구현한 코드를 함께 작성해야 하기 때문에 개발의 집중력을 떨어뜨리고 결과적으로 전체 생산성의 저하를 가져온다. 또 모듈별로 개발자들을 구분하고 분산시키는 것이 한계를 가질 수밖에 없다.
◆ 재활용성의 저하 : 이미 언급했듯이 OOP의 장점인 재활용성이 매우 떨어진다.
◆ 변화의 어려움 : 한번 작성된 시스템은 새로운 요구사항이 생겼을 경우에 전체적으로 많은 부분에 영향을 미치는 경우 쉽게 새로운 요구사항을 적용하기 힘들게 된다. 또 새로운 관심영역의 등장이나 이의 적용을 매우 어렵게 한다. 좋은 툴의 도움 없이는 리팩토링을 하는 것도 어렵게 된다.
이러한 문제점을 AOP를 적용하면 어떻게 될 것인지 <리스트 1>의 클래스를 만약 AOP를 이용한 시스템에서 작성을 했을 때의 코드로 살펴보자.
public class AccountTransfer extends AbstractAccountModule {
public void transafer(Accouno fromAcc, Account toAcc, int amount) {
if (fromAcc.hasEnoughMoney(amount) == false) {
throw new AccountException(“not enough money”);
}
fromAcc.withdraw(amount);
toAcc.credit(amount);
}
…
}
놀랍게도 AOP를 적용하지 않았을 때의 코드에 비해 매우 심플한 구조로 바뀌었다. 계좌이체 모듈을 객체지향적으로 설계했을 때 그 설계에 나오는 핵심기능 코드만 존재하게 된 것이다. 그럼 이렇게 작성된 코드가 앞에서 작성된 코드와 똑같은 기능과 방식으로 동작할수 있는 것인가? 그렇다. 새로운 캠페인을 위한 통계코드나 로깅모듈이 바뀌는 일이 일어나도 이 핵심 관심 코드는 결코 변하지 않는다. 문제영역 자체가 바뀌지 않는 한 이 코드는 그대로 사용할 수 있다. 만약 같은 요구조건과 기능을 가진 다른 은행이 이 코드를 가져다 쓰고 싶더라도 거의 코드에 손을 대지 않고 재사용이 가능하다. 물론 로그, 보안, 인증, 퍼시스턴스 등의 처리 방법과 환경이 완전히 달라진다고 해도 상관없다.
![]() |
<그림 3> 위빙 |
그렇다면 그 많은 로그 처리와 보안, 트랜잭션 관리, 예외상황 처리등의 코드는 어디로 간 것인가? 그 부분은 독립된 형태의 단일 모듈로 각각 작성이 되고 AOP를 통해서 필요한 시점에서 핵심 코드에 삽입되어져 동작하게 된다.
AOP의 동작원리
AOP가 핵심 관심 모듈의 코드를 직접 건드리지 않고 필요한 기능이 작동하도록 하는 데는 위빙(weaving) 또는 크로스컷팅(crosscutting)이라고 불리는 특수한 작업이 필요하다. 핵심 관심 모듈이 자신이 필요한 횡단 관심 모듈을 찾아 사용하는 대신에 AOP에서는 위빙 작업을 통해 핵심 관심 모듈의 사이사이에 필요한 횡단 관심 코드가 동작 하도록 엮어지게 만든다. 이를 통해 AOP는 기존의 OOP로 작성된 코드들을 수정하지 않고도 필요한 횡단 관심 기능을 효과적으로 적용해 낼 수 있다.
이런 작업은 기존의 자바 언어와 컴파일러에서는 쉽게 구현할 수 있는 방법이 아니다. 현재의 AOP 언어와 툴이 개발되기 전에는 크게 두 가지 방법으로 AOP와 비슷한 기능을 구현해보려는 시도가 있었다. 첫째는 EJB와 같은 컨테이너 또는 서버를 이용한 방법이다. EJB는 트랜잭션과 보안, 오브젝트 풀링과 같은 횡단 관심 기능을 컨테이너를 통해 그 위에서 동작하는 EJB 모듈에 적용하고 있다. 일종의 엔터프라이즈 서비스 기능인 EJB의 이러한 처리 방식은 EJB가 엔터프라이즈급 애플리케이션 개발과 운영에 적극적으로 수용되는 만큼 중요한 이유 중의 하나이다. 하지만 EJB는 제공할 수 있는 서비스가 매우 제한적이고 임의의 서비스 추가 등이 불가능하기 때문에 본격적인 AOP 방법으로 사용되기는 어렵다. 더군다나 컨테이너 위에서만 특별한 스펙에 따라 작성된 코드와만 연동해서 동작하기 때문에 POJO(Plain Old Java Objects) 기반의 일반 애플리케이션에는 적용하기가 불가능하다.
두 번째 시도된 방법은 JDK 1.3부터 지원되기 시작한 다이내믹 프록시(Dynamic Proxy)를 이용한 인터셉터 체인(interceptor chain)기술이다. JBoss를 비롯한 컨테이너 개발자들을 통해 많이 사용된 방식이다. 하지만 다이내믹 프록시를 이용한 코드는 구현이 매우 복잡하고 특정 구조의 애플리케이션 틀을 따라 작성되어야만 적용 가능하며, 역시 복잡한 프레임워크 내지는 컨테이너의 도움이 필요하다는 면에서 쉽게 일반화되지는 못했다.
본격적인 AOP 기술이 등장한 것은 1990년대 후반 제록스 PARC 연구소에서 그레거 킥제일(Gregor Kiczales)에 의해 AspectJ가 개발되면서라고 볼 수 있다. 그는 Asepct라는 용어와 함께 AOP라는 표현을 처음 사용하기 시작했고, 자바 VM과 호환되는 최초의 AOP 툴인 AspectJ를 구현해 냈다. AspectJ는 자바의 언어를 확장한 형태의 구조로 개발됐는데 자바의 클래스와 유사한 개념인 AOP의 애스팩트(Aspect)를 작성하는 방법을 통해 AOP의 기능을 사용할 수 있도록 했다. 이렇게 만들어진 애스팩트는 AspectJ의 특별한 컴파일러를 통해 자바 VM에서 사용될 수 있는 코드로 만들어진다. 바로 이때 AOP의 위빙 작업이 일어난다. 위빙 작업을 통해 핵심 관심 모듈의 사이사이에 애스팩트 형태로 만들어진 횡단 관심 코드들이 삽입되어 애스팩트가 적용된(woven) 최종 바이너리가 만들어지는 것이다.
AOP를 이용하면 개발자들은 횡단 관심 모듈을 각각 독립된 모듈로 중복 없이 작성하고 이를 위빙을 통해 핵심 관심 모듈과 결합시키기 때문에 서로 독립성을 가진 다 차원의 모듈을 작성할 수 있다. 앞에서 작성한 AccountTransfer 클래스에 적용할 메쏘드 처리의 시작과 끝을 기록하는 로그 작성용 애스팩트의 코드를 살펴보자.
public aspect MethodLoggingAspect {
Logger logger = MyLog.getLogger(“methodcall”);
pointcut methodcall() : execution (void AccountTransfer.transfer(..)) &&
!within(MethodLoggingAspect);
before() : methodcall() {
logger.begin(thisJoinPointStaticPart.getSignature().getName());
}
after() : methodcall() {
logger.end(thisJoinPointStaticPart.getSignature().getName());
}
}
기존의 자바 언어의 문법을 확장한 구조를 가지는 AspectJ에서는 횡단 관심 모듈을 aspect라는 키워드를 가지는 코드로 작성이 가능하다. 앞의 MethodLoggingAspect를 작성한 후 AspectJ의 컴파일러를 사용해 컴파일을 하고 AccountTransfer의 transfer() 메쏘드를 실행시키면 메쏘드의 실행 전후에 메쏘드의 시작과 끝을 알리는 로그가 만들어진다.
이렇게 만들어진 애스팩트는 기존의 코드에 전혀 영향을 주지 않고 자연스럽게 위빙되기 때문에 핵심 관심 모듈을 개발하는 개발자들은 이 부분을 전혀 고려하지 않고 그 모듈 자체의 로직에만 충실히 작성하고 후에 필요한 애스팩트를 만들어 적용할 수 있다. 앞의 애스팩트 코드는 AccountTransfer 클래스의 transfer 메쏘드에만 적용하도록 한 것이다. 필요하면 포인트컷을 적용해서 애플리케이션 내의 모든 메쏘드에 로그를 남기는 애스팩트가 위빙되도록 할 수 있다. 간단히 포인트컷 시그니처만 수정해주면 된다.
pointcut methodcall() : execution(* *.*(..)) && !within(MethodLoggingAspect)
이제 그 숫자와 상관없이 모든 애플리케이션의 메쏘드의 시작과 끝을 로그로 남길 수 있게 되었다. 만약 로그를 작성하는 코드가 달라져야 한다면 이제는 애스팩트만을 수정해주는 것으로 모든 메쏘드의 로깅 방법을 한 번에 변경할 수 있다. AOP를 사용하지 않고 일일이 모든 메쏘드의 로그 코드를 수정했던 것과 비교하면 굉장히 편리해졌음을 알 수 있다.
AOP의 구성요소
AOP에는 새로운 용어가 많이 등장한다. 이 중에서 특히 AOP를 이용해서 개발하는데 필요한 중요한 구성요소들에 대한 정의를 정확히 이해해야 한다.
조인포인트
횡단 관심 모듈의 기능이 삽입되어 동작할 수 있는 실행 가능한 특정위치를 말한다. 예를 들어 메쏘드가 호출되는 부분 또는 리턴되는 시점이 하나의 조인포인트(jointpoint)가 될 수 있다. 또 필드를 액세스하는 부분, 인스턴스가 만들어지는 지점, 예외가 던져지는 시점, 예외 핸들러가 동작하는 위치, 클래스가 초기화되는 곳 등이 대표적인 조인포인트가 될 수 있다. 각각의 조인포인트들은 그 안에 횡단 관심의 기능이 AOP에 의해 자동으로 추가되어져서 동작할 수 있는 후보지가 되는 것이다.
포인트컷
포인트컷(pointcut)은 어떤 클래스의 어느 조인포인트를 사용할 것인지를 결정하는 선택 기능을 말한다. AOP가 항상 모든 모듈의 모든 조인포인트를 사용할 것이 아니기 때문에 필요에 따라 사용해야 할 모듈의 특정 조인포인트를 지정할 필요가 있다. 일종의 조인포인트 선정 룰과 같은 개념이다. AOP에서는 포인트컷을 수행할 수 있는 다양한 접근 방법을 제공한다. AspectJ에서는 와일드카드를 이용한 메쏘드 시그니처를 사용한다.
어드바이스 또는 인터셉터
어드바이스(advice)는 각 조인포인트에 삽입되어져 동작할 수 있는 코드를 말한다. 주로 메쏘드 단위로 구성된 어드바이스는 포인트컷에 의해 결정된 모듈의 조인포인트에서 호출되어 사용된다. 일반적으로 독립적인 클래스 등으로 구현된 횡단 관심 모듈을 조인포인트의 정보를 참조해서 이용하는 방식으로 작성된다. 인터셉터(intercepter)는 인터셉터 체인 방식의 AOP 툴에서 사용하는 용어로 주로 한 개의 invoke 메쏘드를 가지는 어드바이스를 말한다.
위빙 또는 크로스컷팅
포인트컷에 의해서 결정된 조인포인트에 지정된 어드바이스를 삽입하는 과정이 위빙이다. 위빙은 AOP가 기존의 핵심 관심 모듈의 코드에 전혀 영향을 주지 않으면서 필요한 횡단 관심 기능을 추가할 수 있게 해주는 핵심적인 처리과정이다. 다른 말로 크로스컷팅(crosscutting)이라고 하기도 한다. 위빙을 처리하는 방법은 후처리기를 통한 코드생성 기술을 통한 방법부터 특별한 컴파일러 사용하는 것, 이미 생성된 클래스의 정적인 바이트코드의 변환 또는 실행 중 클래스로더를 통한 실시간 바이트코드 변환 그리고 다이내믹 프록시를 통한 방법까지 매우 다양하다.
인트로덕션 또는 인터타입 선언
인트로덕션(Introduction)은 정적인 방식의 AOP 기술이다. 동적인 AOP 방식을 사용하면 코드의 조인포인트에 어드바이스를 적용해서 핵심관심 코드의 동작 방식을 변경할 수 있다. 인트로덕션은 이에 반해서 기존의 클래스와 인터페이스에 필요한 메쏘드나 필드를 추가해서 사용할 수 있게 해주는 방법이다. OOP에서 말하는 오브젝트의 상속이나 확장과는 다른 방식으로 어드바이스 또는 애스팩트를 이용해서 기존 클래스에 없는 인터페이스 등을 다이내믹하게 구현해 줄 수 있다.
애스팩트 또는 어드바이저
애스팩트(aspect)는 포인트컷(어디에서)과 어드바이스(무엇을 할 것인지)를 합쳐놓은 것을 말한다. 필요에 따라서 인트로덕션도 포함할 수 있다. AspectJ와 같은 자바 언어를 확장한 AOP에서는 마치 자바의 클래스처럼 애스팩트를 코드로 작성할 수 있다. AOP 툴의 종류에 따라서 어드바이스와 포인트컷을 각각 일반 자바 클래스로 작성하고 이를 결합한 어드바이저 클래스를 만들어서 사용하는 방법도 있다.
대표적인 AOP 툴
AOP는 OOP의 확장에 가깝기 때문에 전용 언어나 독립된 개발 툴을 가지고 있지 않고 대신 기존의 OOP를 확장한 언어 확장(languageextension) 또는 툴이나 프레임워크 형태로 사용할 수 있게 되어 있다. 현재 자바에서 사용할 수 있게 구현된 AOP의 숫자는 10여개가 된다. 하지만 이 중에서 주로 사용되는 대표적인 AOP 솔루션은 4가지 정도를 꼽을 수 있다. 대표적으로 AOP 구현의 시초가 된 이클립스 프로젝트의 AspectJ를 들 수 있다.
AspectJ는 초기에 제록스 PARC 연구소에서 개발되었다가 2002년에 이클립스 프로젝트에 기증되었고, 현재 IBM의 전폭적인 지원을 받으면서 개발되어 사용되고 있다. 그리고 BEA가 중심이 되어 개발하고 있는 AspectWerkz가 있다. AspectWerkz는 AspectJ와 달리 자바 언어 자체를 확장하지 않고 기존의 자바 언어만으로 AOP의 사용이 가능하도록 되어 있다. 그리고 의존성 삽입(Dependency Injection, 이하 DI) 기반의 프레임워크로 유명한 SpringAOP가 있다. 가장 최근에 등장한 AOP로는 JBossAOP도 있다. SpringAOP와 함께 대표적인 인터셉터체인 방식의 AOP로 꼽힌다.
![]() |
<표 1> AOP 툴의 비교 |
이렇게 많은 AOP 툴이 존재하는 이유는 아직 AOP가 표준 스펙이나 기준이 없이 현장을 중심으로 빠르게 진화하고 있는 기술이기 때문이다. 기본적인 AOP에 개념은 비슷하지만 실제 구현하는 방법이나 적용 기술은 상당한 차이가 있다. 이 중에서 무엇이 제일 나은 자바 기반의 AOP 하나를 선정하기는 어렵다. 그 이유는 AOP가 사용되는 방식과 목적, 환경에 따라 각기 다른 장단점을 가지고 있기 때문이다. 이렇게 다양한 툴이 존재하는 것이 처음 AOP를 접근하는 개발자들에게는 부담이 되는 것이 사실이다. 하지만 각각의 AOP가 끊임없이 새로운 기능을 시도하고 발전하는 과정을 통해 AOP가 더욱 견고하고 풍부한 기능을 가질 수 있을 것을 기대해 볼 수 있을 것이다.
AspectJ
AspectJ의 가장 큰 특징은 다른 AOP 툴과는 달리 자바 언어를 확장해서 만들어진 구조라는 것이다. 마치 새로운 AOP 언어를 사용하듯이 aspect라는 키워드를 이용해 애스팩트나 포인트컷, 어드바이스를 만들 수 있다. 따라서 일반 자바 컴파일러로는 컴파일이 불가능하고 특별한 AOP 컴파일러를 사용해야 한다. 하지만 이렇게 만들어진 바이너리는 표준 JVM에서 동작 가능한 구조로 되어있기 때문에 특별한 클래스 로더의 지원 없이도 실행 가능하다.
AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴이다. 동시에 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기 때문에 가장 이상적인 AOP 툴로 꼽히고 있다. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고 프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. 위빙이 컴파일시에 일어나기 때문에 포인트컷에 의해 선택된 모든 클래스들은 애스팩트가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.
AspectJ는 가장 오래되고 가장 많이 사용되는 AOP 툴이다. 동시에 가장 풍부한 기능을 가지고 있고 확장성이 뛰어나기 때문에 가장 이상적인 AOP 툴로 꼽히고 있다. 하지만 자바 언어를 확장했기 때문에 새로운 문법과 언어를 이해할 필요가 있고 프로젝트 빌드시 특별한 컴파일러를 사용해야 하는 불편함이 있다. 위빙이 컴파일시에 일어나기 때문에 포인트컷에 의해 선택된 모든 클래스들은 애스팩트가 바뀔 때마다 모두 다시 컴파일이 되어야 한다.
AspectWerkz
AspectWerkz는 AspectJ와는 달리 자바 언어를 확장하지 않는다. 따라서 표준 자바 클래스를 이용해서 AOP를 구현해 낼 수 있다. 일반 클래스와 메쏘드를 이용해 쉽게 구현이 가능한 어드바이스와 달리 복잡한 문법이 필요한 포인트컷은 별도의 XML 파일을 이용해 설정할 수 있도록 되어 있다. 자바 클래스와 XML 설정 파일의 접근법에 익숙한 개발자들에게는 매우 편리한 접근 방식이라고 볼 수 있다.
최근에는 JDK5의 지원에 따라 어노테이션을 이용할 수 있어 더욱 편리해졌다. 위빙은 특별한 클래스 로더를 이용한 로딩타임 바이트코드 생성을 이용한다. AspectJ 못지않은 다양한 조인포인트와 AOP기능을 지원하고 있으며 편리한 개발을 위한 IDE 플러그인이 개발되어 있다.
JBossAOP
JBossAOP는 앞의 두 가지 툴과 달리 프록시를 이용한 인터셉터 체인을 활용해서 위빙을 처리하는 것이 특징이다. 필요에 따라서 JavaAssist를 통한 바이트코드 조작을 이용하기도 한다. JBossAOP는 원래 JBoss 서버의 EJB를 위한 인터셉터 체인 기술을 통해 발전해 왔다. JBoss는 최초로 디플로이 시점의 코드 생성이 아닌 인터셉터 체인을 이용한 방식으로 EJB 호출과 그 사이에 필요한 엔터프라이즈 서비스 기능의 삽입을 구현해냈고 이를 발전시켜 왔다. 최근 EJB3나 하이버네이트와 같은 POJO 기반의 엔터프라이즈 개발이 활발해지면서 좀 더 범용적으로 AOP를 사용할 수 있는 형태로 JBossAOP를 개발했다.
JBossAOP는 기본적으로 컨테이너에서 동작하지만 컨테이너와 상관없는 독립된 자바 프로그램에서도 사용할 수 있다. 하지만 주 용도는 JBoss 서버와 앞으로 나올 EJB3 컨테이너 등에 AOP를 적용하는 데에 사용되어지는 것이다. AspectWerkz와 마찬가지로 어드바이스는 표준 자바 코드로 작성하고 포인트컷과 다른 설정은 XML 파일이나 JDK5의 어노테이션으로 작성할 수 있다. 아직까지는 JBoss 사용자의 일부에서만 사용되고 있으나 향후 EJB3를 중심으로 한 POJO 기반의 엔터프라이즈 미들웨어 프레임워크가 개발되어짐에 따라 점차로 사용률이 올라갈 것으로 기대된다.
SpringAOP
SpringAOP는 스프링 프레임워크의 핵심기능 중의 한가지로 스프링의 DI 컨네이너에서 동작하는 엔터프라이즈 서비스에서 주로 사용된다. SpringAOP는 다른 AOP와 달리 기존 클래스의 바이트코드를 수정하지 않는다. 대신 JDK의 다이내믹 프록시를 사용해서 프록시방식으로 AOP의 기능을 수행한다. 이 때문에 다른 AOP의 기능과 비교해서 매우 제한적인 부분만을 지원한다.
하지만 SpringAOP의 구현 목적은 엔터프라이즈 애플리케이션에서 주로 사용되는 핵심적인 기능에 AOP의 장점을 살려 이를 스프링내에서 사용하는 것이기 때문에 다른 AOP와 같은 AOP의 복잡한 전체 기능을 굳이 다 필요로 하지 않는다. 프록시 기반의 SpringAOP는 SpringIoC/DI와 매우 긴밀하게 연동이 된다. 따라서 SpringAOP를 사용하는 방법은 스프링 내에 프록시 빈을 설정해서 쉽게 사용할
수 있다.
JDK의 표준 기능만을 사용하기 때문에 특별한 빌드 과정이 필요없고 클래스 로더를 변경한다거나 하는 번거로운 작업이 없다. 대신 조인포인트가 종류가 메쏘드 기반으로 제한되며 같은 클래스 안의 메쏘드 호출이나 콜백 코드를 사용했을 경우에는 프록시를 적용할 수 없는 단점이 있다. 하지만 대부분의 엔터프라이즈 애플리케이션에서 필요로 하는 주요 AOP 기능들을 메쏘드 호출을 기반으로 충분히 처리가 가능하기 때문에 SpringAOP는 그 제한된 AOP 기능에도 불구하고 현장에서 가장 빠른 속도로 적용되어 사용되는 AOP 솔루션 중의 하나이다. SpringAOP는 어드바이스와 포인트컷을 모두 표준 자바 클래스로 작성할 수 있다.
필요에 따라서 포인트컷은 설정 파일 내에서 포인트컷 팩토리 빈을 이용해서 정규식으로 표현이 가능하다. SpringAOP의 최대 단점은 복잡한 프록시 설정 구조이다. Spring빈을 정의한 파일에서 프록시를 정의한 부분의 다른 XML기반의 AOP에 비해서도 복잡한 편인데 이 경우 SpringAOP가 지원하는 AutoProxyingCreatorBean 등을 이용하면 설정 코드를 매우 단순하게 작성하는 것이 가능하다.
AOP의 과제
지난 5년간 AOP가 등장하고 현장에 적용되면서 항상 모든 개발자들에게 좋은 반응만 얻은 것은 아니다. 오히려 OOP에 익숙한 많은 개발자들과 학자, 연구원들에게서 강한 저항을 느낄 수 있을 정도로 반발이 있었다. AOP를 반대하는 대표적인 사람이 자바의 창시자인 제임스 고슬링(James Gosling)인데 그는 AOP가 자바의 OOP 정신과 원칙을 훼손하고 그로인해 실전에서 개발자들에게 도움이 되기보다는 어려움을 주는 문제를 안고 있다고 비판한다.
하나의 새로운 프로그래밍 패러다임이 등장하고 발전하면서 완전히 자리를 잡아가기까지는 그만큼 충분한 시간이 필요할 것이고, 그 이전 세대 패러다임과의 적지 않은 충돌을 예상해야 하는 것은 분명하다. AOP는 다른 프로그래밍 패러다임보다 훨씬 빠른 시간에 현장 실무에 적용되고 자리를 잡아나가고 있고 많은 개발자들의 호응에 힘입어 놀라운 성장을 보여주고 있음에도 주류 기술로 자리 잡기 위해서는 해결해야 할 여러 문제점과 극복할 장벽을 가지고 있는 것이 사실이다.
표준의 부재
AOP는 현재 정해진 표준이 없으며 표준을 정할 기구나 조직도 없다. 용어부터 시작해서 문법, 구현 방법에 이르기까지 AOP와 관련해서 통일된 것이 없다. 따라서 AOP 툴을 만드는 팀과 업체에 따라서 그 내용과 형식이 상당히 차이가 나는 경우도 있다. 비록 기본적인 개념은 공유하고 있다고 하지만 접근 방법이 차이가 나는 것은 AOP가 프로그래밍 표준 기술로 자리 잡는데 많은 장애가 될 수밖에 없다. 이로 인해 처음 AOP를 접하는 개발자들이나 AOP를 공부하려는 사람들에게 혼란을 안겨 주기도 한다.
이런 와중에 AOSD(Internationl Conference on Aspect Oriented Software Development)와 같은 행사들이 꾸준히 열리면서 AOP 연구자들과 툴 개발팀, 개발자들 사이에 많은 의견을 모으고 표준을 위한 노력이 시작되었다는 것은 반가운 소식이다. 또한 최근 AOP툴 업체들 간에 협력이나 통합 구조가 가시적으로 보이고 있다는 것 또한 매우 좋은 현상이라고 본다. 특히 올해 들어 대표적인 AOP 툴인 AspectJ와 AspectWerkz가 협력해서 통합된 AOP 툴을 만들기로 하고 지금 작업이 진행 중이라는 사실은 매우 고무적이다.
게다가 최근 AspectJ 프로젝트를 이끄는 핵심 개발자인 아드리안 콜리어(Adrian Colyer)가 그동안 몸담고 있으면서 AspectJ를 개발해 왔던 IBM을 떠나 SpringAOP를 만든 Interface21에 합류하게 되었다. 이로 인해 3개의 AOP 툴의 장기적인 통합도 기대할 수 있을 것 같다. 하지만 한편으로는 표준을 빨리 제정하기 보다는 아직은 AOP는 발전하고 진화해야 하는 단계에 있기 때문에 다양한 창조적인 시도들이 가능한 현 상태가 어느 정도 더 유지되어져야 할 것이라는 의견도 있다.
학습의 어려움
현장에서 AOP를 접해온 개발자들의 가장 큰 AOP에 대한 비판은 AOP가 너무 어렵다는 것이다. AOP를 배우는 것은 기존 OOP에 대한 완벽한 지식을 바탕으로 한다고 해도 사실 상당한 발상의 전환이 필요하고 그 개념이 난해한 부분이 많다. 새로운 용어들에 익숙해지고 그 의미를 정확히 파악하는 것 또한 만만한 것이 아니다. 게다가 이를 기존 애플리케이션에 어떻게 적용해야할지 그 적용 방법과 아이디어를 내는 것도 수월하지 않다. 더 나아가서 AOP로 개발된 애플리케이션을 보고 이해하는 것도 어려움이 있다고 지적한다.
학습과 적응의 어려움은 OOP가 등장하고 현장에 적용되던 초기와 다를 바 없다고 생각된다. 프로시저 기반의 프로그래밍에 익숙한 개발자들에게 객체지향 언어와 개념은 매우 난해했고 상당한 시간이 지나기까지 개발자들이 매우 어려워했던 것은 사실이다. 아직도 OOP의 개념과 원리에 대해서 또는 OOAD에 대해 힘들어 하는 개발자가 많은 게 사실이다. AOP도 또한 초기에는 그러한 적응의 과정이 필요할 것이다. 더 많은 개발자들과 이론가들이 충분히 그 기술과 개념에 익숙해져야 할 시간이 필요할 것이고, 또 AOP 기반의 애플리케이션을 설계하고 구현하는데 필요한 다양한 방법론과 설계 기술들이 등장하게 될 것이라고 보여 진다.
문제는 후자의 경우인데 AOP로 만든 프로그램은 프로그램의 흐름을 이해하고 추적하기가 매우 힘들다는 주장이다. 이는 AOP에 대한 오해에서 비롯된 주장이라고 보여진다. 필자를 포함해서 많은 AOP를 이용해서 애플리케이션을 개발하는 개발자들의 공통적인 의견은 AOP를 적용한 후가 그렇지 않을 때에 비해 애플리케이션의 구성과 코드가 깔끔해졌고 그로 인해 전체 애플리케이션을 이해하고 교육하고 유지보수하기가 한결 쉬워졌다는 것이다. 물론 AOP는 매우 다차원적으로 시스템을 이해하고 접근하기 때문에 역시 해석 또한 다차원적이어야 한다는 부담감이 있다. 대신에 각 차원의 독립된 관점에 따라서 애플리케이션을 살펴보고 이를 통합해서 생각하는 훈련만 된다면 이전에 많은 다른 차원의 코드들이 섞여있던 때에 비해 애플리케이션에 대한 이해는 훨씬 수월해질 것이라고 기대된다.
OOP와의 충돌
AOP의 비판자들 중 상당수는 AOP가 OOP의 정신을 훼손하고 OOP의 중요 원칙을 깨뜨린다고 한다. 이 부분은 아직도 많은 논쟁이 진행중인 부분이다. 대표적으로 AOP는 OOP의 캡슐화를 깨뜨리고 객체의 내부에 직접적인 영향을 줄 수 있기 때문에 객체지향적인 장점을 손상하고 시스템을 복잡하게 만든다고 한다. 기존의 클래스와 코드의 어떤 부분에라도 영향을 줄 수 있다는 면에서 일견 일리가 있는 주장이다. 하지만 AOP가 없이 그러한 횡단관심 기능을 핵심 모듈 내부에 직접 작성해서 쓰는 것은 과연 객체지향의 원칙에 맞는 일인가? 그게 아니라면 현실적으로 객체지향적인 방법으로 그 부분을 해결할 수 있는 효과적인 방법을 제시해야 할 것이다. 결국 OOP의 한계와 약점이있는 곳에서 AOP가 출발하기 때문에 이것을 노골적으로 드러내는 AOP가 OOP와 충돌하는 것은 어쩔 수 없는 현실이라고 본다.
다만 AOP 만능주의자가 되어 OOP적인 바른 접근과 설계를 뒷전으로 하는 것은 진정한 AOP가 아니라고 생각된다. AOP가 가장 큰 영향을 줄 수 있는 것 중의 하나는 개발방법론을 비롯한 소프트웨어 디자인과 아키텍팅 부분이다. 기존의 BUFD(Big Up Front Design)에 익숙한 객체지향 아키텍트는 딜레마에 빠지기가 쉬운데 이는 초기디자인은 어느 정도까지 하는 것이 적당한 것인지 항상 고민하기 때문이다. 너무 과도한 디자인은 향후 시스템의 개발 과정이나 개발 후에 더욱 발전하거나 변화하는데 장애가 되기 때문에 초기 디자인이 어디까지 나아가야 할 것인가 큰 고민일 수밖에 없다. 이런 상황에서 AOP의 도입은 초기 디자인의 부담을 크게 덜어 줄 수 있다.
핵심 디자인을 거의 손대지 않고도 시스템 전반에 영향을 주는 횡단 관심 모듈을 독립성 있게 개발하고 전 시스템에 걸쳐 자유롭게 삽입, 제거가 가능해지기 때문이다. 따라서 AOP는 XP(Extreme Programming) 방식을 따르는 개발자들에게는 상당히 막강한 무기가 되기도 한다. 동시에 전통적인 디자인 우선 방식을 선택한 아키텍트들에게도 많은 도움이 되고 있는 것도 사실이다. 여기서 한 가지 AOP에 대한 오해가 생기기 쉬운데 AOP가 잘 설계되지 못한 디자인을 완전하게 만들어 줄 것이라는 환상이다. 이는 결코 그렇지 않다. AOP는 이미 잘 설계되어 있는 디자인을 더욱 쉬운 방법으로 적용할수 있게 만들어줄 뿐이다. 이런 면에서 AOP를 쓴다고 해서 기존의 OOP적인 설계와 접근방법을 포기하거나 가볍게 여기는 것은 잘못된 선택이 분명하다.
AOP의 미래
AOP는 갑자기 어디서 떨어진 마법의 만능도구는 아니다. 오히려 현장에서 개발에 매진하는 개발자들이 스스로 기존 기술과 방법의 문제점을 극복하기 위해 찾아낸 개발자를 위한 도구이다. 모든 소프트웨어 기술이 다 그렇듯이 AOP도 결국 좀 더 효과적인 방법으로 더 나은 품질의 제품을 개발하는데 그 존재 가치가 있다. 최근에 불고 있는 POJO 기반의 개발 기술의 열풍은 이러한 근본적인 문제에 대한 개발자 스스로의 반성이 현실로 나타난 것이다. 아드리안 콜리어는 POJO 기반의 애플리케이션 개발의 3대 기술을 AOP, DI, 어노베이션이라고 하고 이 3가지가 앞으로의 시대를 주도하는 핵심 개발 기술이 될 것이라고 이야기한다. 이미 어노테이션은 자바 5의 표준 기술로 자리를 잡았고 의존 삽입 또한 다양한 프레임워크의 지원 하에 매우 빠른 속도로 사실상의 표준 기술로 자리 잡고 있다. 이제 AOP가 주류 기술로 자리 잡을 때가 다가왔다고 보여진다. AOP를 통해 더 나은 애플리케이션 개발을 경험하는 개발자들이 국내에도 많아지게 되기를 기대해본다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
AOP (Aspect Oriented Programming) (0) | 2008.08.03 |
---|---|
[UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」 (0) | 2007.09.27 |
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드 (0) | 2007.09.27 |
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
2008. 8. 3. 04:49 IT 자료/데이터베이스
[자료구조] M-one 탐색 Tree, B-Tree, B*-Tree, B+-Tree, TRIE
M-one 탐색 Tree, B-Tree, B*-Tree, B+-Tree, TRIE
Definition
1 m-one search tree : Binary search tree의 일반화된 형태
2 B-tree : m-one search tree 의 특수 형태이며 균형 Binary search tree의 일반 형태
3 B*-tree, B+-tree : B-tree의 변형
1. Index의 구성
l 일반적으로 보조기억장치에서의 탐색은 시간적인 부하가 많이 걸리기 때문에 탐색을 쉽게 하기 위해 file과는 별도로 index를 만들어 사용한다.
l Index가 커질 경우 Index 역시 보조기억장치에 저장하는데 보조기억장치는 상대적으로 느리므로 보조기억장치의 Access횟수를 최대한 억제시켜야 한다.
l Index에의 Access 횟수를 줄이기 위해서는 최대 탐색길이 즉, tree의 높이를 줄여야 한다.
l 높이를 낮추기 위해서는 하나의 Node에서 나가는 Branch 의 개수를 증가 시킨다.
2. m-one search tree
N |
P(0) |
K(1) |
P(1) |
P(2) |
K(2) |
……. |
P(n-1) |
K(n) |
P(n) |
n : Node에 있는 key 값의 개수
l 한 Node에서 나가는 Branch의 개수를 최대 m개 (m>2)인 tree이다.
l 자식 Node를 최대 m개 가지며 m-1개의 Key 값을 갖는다.
2.1 특징
l 한 Node안에 있는 Key값은 오름차순으로 정렬된다.
l P(0)가 가리키는 종속 tree의 모든 Key 값은 P(1)이 가리키는 종속 tree의 key 값보다 작다.
l P(i)가 가리키는 종속 tree도 m-one search tree이다
Cf) 한 Node안에서 특정 key 값을 찾을 때 그 Node 안에 있는 Key 값의 개수가 많다면 선형탐색보다 이진탐색이 더 효율적일 수 있다.
2.2 성능
l 높이가 h인 m-one tree에서 Node의 최대 개수는 (mh-1)/(m-1) 이다 . 각 Node가 최대 m-1개의 key값을 가지므로 tree 의 전체 key값 개수는 최대 mh-1개이다.
l 전체 key값의 개수가 N인 m-one tree가 최대 높이 h를 갖게 하기 위해서는 m은 적어도 (N+1)1/h이어야 한다.
|
2.3 Binary Search Tree와의 비교
l m-one tree는 높이가 낮고 폭이 넓다. 한 단계씩 탐색과정을 진행할 때마다 Node의 대략 1/m로 줄어든다.
l
Binary Search Tree는 높이가 높고 폭이 좁다. 한 단계가 진행될 때마다 Node의 개수가 1/2로 줄어든다.
그림2. 3-one Search Tree와 Binary search tree의 비교 |
2.4 결론
l m-one tree의 성능을 향상시키기 위해서는 m을 크게 해야 하며 tree를 균형에 가깝도록 해야 한다.
l 균형에 가깝도록 tree의 형태를 만드는 것은 Tree를 처리하기 용이하게 하고 성능의 향상시킬 수 있다. 이런 형태의 tree를 B-Tree라 한다.
3. B-tree
3.1 정의
l 차수 m의 B-tree는 다음의 성질을 갖는다.
1) tree에 있는 각 Node는 최대 m개, 최소 (m/2)개의 종속 tree를 가져야 한다.
ð 이 조건에 의해 tree의 각 Node가 적어도 반 이상은 key값으로 채워져 있도록 한다. 따라서 종속 tree가 없는 Node가 발생하지 않고 key값이 가능한 효율적으로 종속 tree에 분배될 수 있도록 한다.
2) root Node는 최소한 두 개의 종속 tree를 가져야 한다. (단 tree가 root 만 있을 경우 종속 tree는 없다.)
ð 이 조건에 의해 tree가 처음부터 분기하도록 한다.
3) 모든 leaf Node는 같은 level에 있어야 한다. (즉, 모든 leaf Node는 root로부터 같은 거리에 있어야 한다.)
ð 모든 leaf Node가 root로부터 같은 거리에 있도록 하므로 tree가 거의 균형되게 하여 어느 leaf Node를 탐색하든 처리횟수가 같도록 한다.
4) Node의 key값의 개수는 종속 Tree의 개수보다 하나 적으며 최소 (m/2)-1개, 최대 m-1개이다.
정리)
B-tree는 차수 m을 갖는 empty 이거나 empty가 아닐 경우 height >= 1 이며 다음 조건을 만족하는 m-way search tree이다.
l root는 최소한 두 개의 children을 가진다.
l root node와 left node를 제외한 모든 node는 적어도 m/2개의 children을 갖는다.
l 모든 leaf node는 같은 level에 있다.
3.2 m의 선택
l disc에의 접근횟수를 감소시키기 위해서는 높은 차수의 B-tree를 사용하는 것이 바람직하다.
l 하지만 하나의 level만을 가지는 B-tree (m = N+1)의 경우 memory에 모든 key 값을 가져야 하므로 비효율적이다.
|
l 따라서 전체 탐색 시간을 줄일 수 있는 m을 선택하여야 한다.
l 최대 탐색 시간을 구하는 공식
g [ { (a+d) / log2m } + {(dm) / log2m)} + (1000c) ]
g : f * log2{(N+1)/2} f : 임의의 상수
c : 임의의 상수 d : 임의의 상수
a = 탐색시간 + 회전지연시간
b = {Key 값의 문자수 + (record 의 주소를 나타내는 field의 크기 * 2)}
* 문자당 전송시간
ex) key 값이 최대 6문자, record 주소가 3문자일 경우
탐색시간은 1/100 sec, 회전지연시간은 1/40 sec로 계산
3.3 B-tree의 연산
3.3.1 key 값의 순차적 처리
B-tree는 각 node를 중위순회(inorder) 하여 key 값을 순차처리 할 수 있다. 하지만 각 node는 여러 개의 key 값이 있기 때문에 각각의 node를 여러 번 방문하게 된다. 따라서 순차처리에서는 좋은 성능을 나타내지 못한다.
B-tree의 변형 구조에서는 좋은 성능을 기대할 수 있다.
|
3.3.2 Insertion
l Insertion/Deletion 연산 후에도 B-tree는 B-tree의 성질을 보존해야 하며 균형을 이루어야 한다. => 균형 algorithm 필요
l 규칙
Ø key 값은 항상 leaf node에서만 삽입된다.
Ø 새로운 key 값이 삽입된 node의 현재 key 값의 개수에 따라
ð 해당 node가 가득 차지 않았을 때 : 단순히 삽입
ð 해당 node가 가득 찼을 때 : 분열하여 중간 key 값을 부모 node로 보내고 나머지 key 값들을 둘로 나누어 각각 분열된 두 node로 옮긴다.
l 특징
Ø leaf node에서 삽입되고 root에서 자란다.
Ø 한 node가 분열되면 반만 채워진 두 개의 node가 생기므로 그 이후의 삽입은 분열 없이도 수행될 가능성이 높다. 즉, 한 번의 분열에 의해 여러 번의 단순 삽입이 가능해진다.
Ø 부모 node로 올라가는 key 값은 중간 값이므로 어떤 순서로 삽입하든 관계없이 tree 의 균형을 개선시킬 가능성이 많다.
그림5. B-tree 에서의 삽입과정 |
3.3.3 Deletion
l Deletion 연산은 항상 leaf node에서 이루어진다.
l Delete하려는 key 값이 leaf가 아닌 node가 아닌 node가 있다면 후행 key 값과 자리를 바꾸어 leaf node로 옮긴 후 삭제한다.
l 연산 결과 최소한의 key 값 ((m-2)-1)을 갖지 못한다면 재배치(redistribution)나 합병(merge, concatenation)하여 key 값의 개수를 조정한다.
|
3.3.3.1 재배치(redistribution)
Ø 해당 node의 left 또는 right node에 최소 key 값보다 많은 key 값을 갖고 있을 때 사용한다.
Ø 선택된 형제 node로부터 부모 node를 경유하여 key 값을 해당 node로 이동한다.
Ø 하나 이상의 key 값을 이동시켜서 (부모 node와 형제 node, 해당 node의 key 값 중 중간 값을 부모 node로 보내고 나머지를 2개로 나누어 할당한다.) key 값의 분포를 균형 있게 유지하여 tree 의 성능을 개선할 수 있다.
Ø Tree 구조의 변경은 없다.
3.3.3.2 합병 (merge, concatenation)
Ø 재배치가 불가능한 경우 사용
Ø insertion 시 분열의 반대 과정
Ø 부모 node와 형제 node의 key 값과 해당 node의 key 값을 하나의 node로 합병
Ø 합병당한 두 node중 하나를 새로 만들어진 node로 대치하고 나머지 한 node는 제거 한다.
Ø 최악의 경우 root node까지도 변경될 수 있다.
Ø Tree의 구조가 변경된다.
4. B*-tree
4.1 정의
B-tree의 문제점을 보완하기 위해 B-tree를 변형한 구조. 즉, B-tree에서는 제한 조건을 유지하기 위해 삽입과정에서 분열과 삭제과정에서 합병 등의 보조연산이 필요하다. B*-tree에서는 이런 보조연산을 감소시키려 헸다.
4.2 조건
l 각 node는 2/3가량 채워지면 된다. (B-tree는 1/2 이상)
l B*-tree는 node의 분열을 줄여서 보조연산을 줄이려고 한다. 따라서 node가 가득차면 분열하는 대신 이웃한 형제 node로 재배치를 한다.
l 한 node가 가득차고 인접 node까지 모두 가득찰 때까지 분열을 지연한다.
4.3 Insertion
l B-tree에서와 같은 방법으로 삽입을 한다.
l node가 가득차면 이웃한 형제 node를 살펴보아 빈자리가 있으면 정렬하여 재배치한다.
l 그림에서 관련된 전체 key 값은 7개이고 부모 node에 들어갈 한 개를 제외하면 6개가 되고 이 6개의 key값이 두 개의 node로 분할 되므로 6/2=3개씩 node에 분산된다. 그리고 부모 node에는 중간 값이 올라간다.
l 인접 node에도 overflow가 일어나서 더 이상 빈자리가 없을 경우 가득찬 두 node를 분열하여 2/3정도 찬 3개의 node로 만든다.
4.4 Deletion
B-tree와 똑같이 삭제 후 key 값의 개수가 모자라면 이웃한 형제 node로부터 재배치하고 재배치도 할 수 없는 경우 합병한다. 합병할 때는 세 개의 node를 두개의 node로 합병한다.
5. B+-tree
5.1 정의 : B-tree의 변형 구조로 index 부분과 leaf node로 구성된 순차 data 부분으로 이루어진다.
index 부분의 key 값은 leaf에 있는 key 값을 직접 찾아 가는데 사용하고 모든 key 값은 leaf에 나열된다. 즉, index 부분의 key 값도 leaf node에 다시 한 번 나열된다.
leaf node는 순차적으로 linked list를 구성하고 있어서 순차적 처리가 가능하다.
5.2 Insertion
l B-tree와 거의 동일하게 이루어진다.
l Node의 분열이 일어나면 중간 key 값이 부모 node로 올라갈 뿐 아니라 새로 분열된 node에도 포함되어야 한다.
l 새 node는 leaf node끼리의 linked list에도 삽입되어야 한다.
그림7. B+-tree 에서의 삽입과정 |
5.3 Deletion
l 재배치와 합병이 필요하지 않을 때는 leaf node에서만 삭제된다.
l Index 부분은 다른 key 값을 찾는데 사용될 수 있기 때문에 leaf node의 값이 삭제되어도 삭제하지 않는다.
l 재배치할 경우 index 부분의 node의 key 값은 변하지만 tree 구조는 변하지 않는다.
l 합병을 할 경우 index 부분에서도 key 값을 삭제한다.
6. 트라이 (Trie)
6.1 정의
하나의 key 값의 일부분만을 사용하여 분기하는 tree 구조이다. 보통 하나의 node는 m개의 pointer로만 구성된 1차원 배열이며 배열의 각 원소의 주소는 그 주소에 대응하는 숫자를 나타낸다.
예를 들어 key 값이 숫자로 구성된다면 이는 곧 10-one tree이다. 마찬가지로 key 값이 영문자로만 구성된다면 각 node는 26개의 key 값을 갖는 26-one tree가 된다.
Trie의 높이는 key 값의 길이에 의해 결정된다. link가 없는 node의 key 값은 0으로 나타내며 pointer가 모두 0인 node (종속 tree가 없는 node)는 나타내지 않음으로써 높이를 낮추고 기억공간을 절약할 수 있다.
6.2 성능
탐색시 B+-tree와 같이 leaf node까지 가야만 key 값을 찾을 수 있다. 하지만 찾는 key 값이 없을 경우 어느 level에서든지 끝낼 수 있다. 따라서 key 값이 없는 경우의 탐색 효율이 좋다.
6.3 Insertion/Deletion
l 새로운 key 값이 삽입이나 삭제될 leaf node를 찾기 위해서는 특정 key 값을 직접 탐색하여야 한다.
l 삽입시 새로운 node가 들어갈 leaf node가 없는 경우 index 부분에도 node를 삽입해야 한다.
l 위치가 결정되면 해당 위치의 0을 고쳐 key 값이 존재한다는 것을 나타내주거나 key 값의 Record 주소를 저장해야 한다.
l 삭제 시에는 해당 위치의 Pointer를 0으로 만들어 연결을 끊는다.
l Trie에서는 삽입이나 삭제시 node의 분열이나 합병이 없다.
6.4 Trie의 변형
기본 trie를 변형하여 효과적으로 사용할 수 있다.
6.4.1 가변길이의 key field 수용
예를 들어 영문자로만 구성된 이름을 key 값으로 사용하며 최대 key 값은 30로 구성될 때 높이 30인 26-one trie가 필요하다.
만약 key 값의 대부분이 8문자 이내라면 각 node에 27개의 원소를 가지도록 node를 구성하고 마지막 원소는 특수문자 (예를 들면 '$'와 같은)를 사용하여 이름이 끝난다는 표시를 나타내게 한다. 그리고 trie를 8 level로 구성하여 8자 이상인 이름은 이름의 나머지를 가지고 있는 다른 장소 (예를 들면 Binary Search Tree)를 가리키도록 하여 이름의 나머지를 찾도록 한다.
6.4.2 기억 장소 감소
예를 들어 영문자를 사용하는 key 값에서 모든 알파벳 문자를 나타내지 않고 실제 사용하는 알파벳만을 나타내도록 하면 모든 node가 26개의 key 값을 가질 필요가 없으므로 기억장소를 절약할 수 있다.
2007. 9. 27. 21:32 IT 자료/소프트웨어 공학
[UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」
이경원 (한국오라클) 2005/04/11
연재순서 1회. 가능성·확장성 품고 등장한 UML 2.0 2회. 초보자를 위해 다각도로 살펴본 UML 3회. 바로 알고 제대로 쓰는 UML 실전 모델링 4회. 닷넷 환경에서 UML 툴 활용 가이드 5회. 표준을 넘나드는 UML의 적절한 사용 |
음계를 이용하여 아름다운 음악을 작곡하듯이 UML을 이용하여 좋은 소프트웨어를 개발하는, 이른바 UML 사용의 베스트 프렉티스를 생각해야 한다. 간혹 베스트 프렉티스가 UML 표준을 준수하지 않는 경우도 있는데 중요한 것은 표준 준수 여부가 아니라 어느 것이 더 효과적이냐는 것이다. 성공적인 소프트웨어 개발을 위해서라면 표준을 넘나들 수도 있어야 한다.
이에 이번 글에는 유즈 케이스를 중심으로 UML을 잘 표현하기 위한 시맨틱을 제대로 정리하고 사용하는 방법에 대한 고찰해 보겠다.
[유스케이스]는 시스템이 사용자에 의해서 어떠한 형태로 사용되는지를 기술하는 UML의 표준 표기법이다. 다르게 말하면 시스템이 갖추어야 하는 여러 기능적, 비기능적 요구사항(주로 기능적 요구사항)을 표현하는 방법이 [유스케이스]이다. 이전에도 요구사항을 기술하는 방법은 여러 가지가 있었지만 모델링의 표기법이 UML로 통합되면서 유스케이스가 요구사항을 기술하는 일반적인 방법으로 사용되어 오고 있다.
그런데 [유스케이스]는 표준 표기법임에도 불구하고 UML의 다른 표기법에 비해 그 구성 요소가 적고 그것들을 활용해서 표현하는 방식에 있어서 자유도가 매우 높다. UML의 구성 요소 중 UML 사용의 시맨틱적 요소가 가장 큰 것이 [유스케이스]라 할 수 있다. 유스케이스 사용의 다양한 방식들 중 많은 사람들의 지지를 받고 있는 이른바 베스트 프랙티스를 살펴봄으로써 유스케이스의 효과적인 사용법을 알아보기로 하자.
[유스케이스]의 큰 그림
[유스케이스]는 크게 [유스케이스] 모델과 [유스케이스] 기술서로 구성되어 있다. [유스케이스] 모델에 관한 것은 표준에 의해 정의되어 있지만 유감스럽게도 [유스케이스] 기술서는 특별히 표준이라 할 수 있는 것이 없다. 다만 방법론을 다루는 쪽이나 [유스케이스]를 많이 사용해 본 사람들이 [유스케이스] 기술서 작성을 언급할 뿐이다. [유스케이스] 모델은 [유스케이스]의 구성 요소인 액터와 유스케이스, 그리고 그들의 전체적인 관계를 다이어그램의 형태로 가진다. [유스케이스] 모델을 통해 시스템의 전체적인 개요와 구성을 쉽게 알 수 있다. [유스케이스] 모델에 나타난 구성 요소의 세부적인 내용은 [유스케이스] 기술서에 작성한다.
[유스케이스] 모델
[유스케이스]는 소프트웨어 시스템이 무엇을 만들어야 하는지, 어떠한 기능을 제공해야 하는지를 기술하는 표기법을 통칭해서 부르는 말이다. [유스케이스]는 시스템을 사용하는 사용자와 내가 만들어야 하는 시스템 자체를 설명하는 방법이다. [유스케이스]에서는 시스템을 사용하는 사용자를 액터(actor)라 하고 시스템의 행동을 유스케이스(use case)라고 한다. 그리고 내가 만들려고 하는 소프트웨어 시스템을 주제영역(subject)이라고 한다. 내가 만들 시스템에 대한 유스케이스들은 주제영역 안에 존재하고 주제영역 밖의 액터와 연결된다. <그림 1>은 [유스케이스] 다이어그램의 전형적인 예이다.
![]() |
<그림 1> [유스케이스] 다이어그램의 전형적인 예 |
액터라고 해서 모두 사용자를 지칭하는 것만은 아니다. 주제영역으로 정의되는 시스템과 연결되어 상호작용하는 외부 시스템도 액터로 정의한다. 하나의 시스템을 여러 팀이 나누어 개발할 때 다른 팀에서 만든 모듈도 나의 팀의 관점에서 본다면 액터로 정의할 수 있다. 쉽게 말해서 내가 만들어야 하면 유스케이스이고 남이 만들면 액터가 된다. <그림 1>과 같은 [유스케이스] 다이어그램을 통해 시스템이 어떠한 액터들과 상호작용하며 어떤 기능을 액터에게 제공하는 지를 일목요연하게 알 수 있다.
[유스케이스] 모델 구성 요소에 대한 세부적인 내용은 [유스케이스] 기술서에 정의하고 [유스케이스] 다이어그램에서는 어떤 [유스케이스] 기술서와 연결되는지 정도를 첨가해 주면 된다. 이는 현존하는 대부분의 UML 모델링 툴이 지원해 주는 기능이다.
‘역할’을 뜻하는 액터
액터는 시스템의 사용자 측면을 정의할 때 사용한다. 액터는 보통 특정 작업을 완수할 목적으로 시스템과 상호 작용하는 사람이나 시스템이 수행하는 역할이라고 정의하고 <그림 2>와 같이 표기한다.
![]() |
<그림 2> 액터를 형상화한 모습 |
액터는 역할에 더 가깝기 때문에 사람 이름보다 직책 이름이 많이 사용된다. 만약 웹사이트 애플리케이션이라면 사이트 회원, 비회원, 관리자 등이 액터로 사용될만한 것들이다.
관심을 갖고 있는 주제영역 시스템과 상호작용하는 외부 시스템도 전형적인 액터이다. 외부 시스템은 주제영역 내의 시스템의 요청에 따라 정보를 제공하는 것이 일반적이다. 전자상거래가 필요한 시스템이라면 외부 시스템으로 신용 정보나 금융 정보 등을 제공하는 시스템을 생각할 수 있고, 여행 상품을 제공하는 시스템이라면 외부 시스템으로 호텔 예약 시스템이나 교통편 예약 시스템 등을 생각할 수 있겠다. 다음은 액터의 전형적인 사례이다.
◆ 사람 : 텔레마케터, 관리자 등
◆ 외부 시스템 : 신용 정보 시스템, 예약 시스템 등
◆ 장치 : 온도 감응 장치, 출입 통제 장치 등
◆ 외부 조직 : 금융감독원, 보안 조직 등
◆ 이벤트 : 매일 밤 12시, 월급날 등
이벤트도 액터?
액터는 시스템의 기능적 요구사항을 정의할 때 매우 유용하게 사용된다. 특히 이벤트 발생 시점과 같은 액터는 시스템의 기능적 요구사항을 정의하는 데 매우 유용하다. 주기적으로 수행되는 배치 작업이 일반화되어 있는 현대의 시스템에서 이벤트 발생 시점은 매우 훌륭한 액터가 된다.
사실 시간과 같은 이벤트를 액터로 해도 되느냐 하는 부분에 대해서는 논란의 여지가 있는 것도 사실이다. 액터는 시스템을 사용함으로써 원하는 목적을 달성하려는 사람 혹은 외부 시스템으로 정의하기도 하는데, 시간 자체는 특별한 목적을 가지지 않기 때문에 액터로 해서는 안 된다고 주장하는 경우도 있다.
[유스케이스]는 그 사용에 있어 자유도가 높기 때문에 이러한 논쟁이 유달리 많기도 하다. 중요한 것은 시스템의 요구사항을 [유스케이스]로 정의하고 보다 많은 사람이 그것을 통해 서로의 생각을 얼마나 잘 공유할 수 있느냐는 것이다. 이벤트를 액터로 하는 것은 시스템의 기능 정의에 많은 도움이 된다고 생각한다.
액터의 분류
[유스케이스]의 창시자인 이바 야콥슨은 액터를 주요(primary) 액터와 보조(secondary) 액터의 두 가지로 분류했다. 주요 액터는 시스템에 어떠한 작업의 실행을 요구하는 능동적인 입장의 액터로 유스케이스를 기동하는 역할을 수행한다. 보조 액터는 시스템의 요청에 따라 수동적으로 어떤 작업을 해 주는 액터로써 유스케이스로부터 어떠한 요청이나 메시지를 전달 받는 액터를 말한다. 최근에는 액터를 더 세분화해서 분류하기도 하는데, 액터의 성격에 따라 크게 네 가지로 나눌 수 있다.
◆ 유스케이스를 기동시키는 액터
◆ 시스템의 요청에 따라 정보를 제공하는 외부 액터
◆ 시스템이 제공하는 정보를 단순히 수신하는 액터
◆ 다른 액터와 시스템간의 상호 작용을 돕는 프록시 역할의 액터
네 가지 액터 유형 중 특이한 것이 프록시 역할을 하는 액터이다. 액터는 유스케이스와 연결될 뿐 액터와 액터는 서로 연결되지 않게 하는 것이 일반적인 액터의 설계 방식으로 여겨져 왔다. 그러나 액터끼리 서로 연결되게 모델링을 하는 것이 시스템을 좀 더 이해하기 쉽게 만드는 경우도 있다.
![]() |
<그림 3> 전화로 예약을 받는 시스템 |
<그림 3>은 전화로 예약을 받는 시스템의 예이다. 시스템을 직접 사용하는 사용자는 전화를 받는 창구 직원이 되겠지만 예약이라는 목적을 가지는 것은 고객이기 때문에 고객이 창구 직원에게 전화를 걸어 시스템을 사용하는 것은 <그림 3>처럼 모델링하는 것이 보다 효과적이게 된다. <그림 3>과 같은 시스템은 보통 클라이언트/서버 유형이 애플리케이션인 경우가 많은데 이후 시스템을 웹으로 확장시켜 고객이 직접 웹 사이트를 통해 예약이 가능하도록 하게 되면 창구 직원 액터가 웹을 통한 예약 유스케이스로 변환될 수도 있다.
유스케이스
시스템이 액터에게 주목한 만한 결과를 내놓기 위해 수행하는 여러 작업들의 집합을 유스케이스라고 한다. 즉, 앞서 나온 예약 접수나 구매 주문, 주문 현황 점검과 같은 것들이 유스케이스이다. 유스케이스는 시스템이 수행하는 특정 기능에 대해서 그 기능의 수행을 원하는 액터와 시스템간의 상호 작용과 시스템 내부에서 발생하는 모든 가능한 사항을 기술한다. 유스케이스는 <그림 4>와 같이 표기한다.
![]() |
<그림 4> 유스케이스 |
유스케이스의 구성 요소는 여러 가지가 있지만 이름과 작업 흐름이 제일 중요하다. 유스케이스 이름은 [유스케이스] 모델에서 중요하고 작업 흐름은 [유스케이스] 기술서에서 중요하다. 유스케이스의 이름을 지을 때는 동사나 동사구의 형태로 능동형을 사용하는 것이 좋다. 유스케이스의 작업 흐름을 기술할 때 유의해야 할 점은 ‘무엇’에 대한 것을 작성해야 한다는 것이다.
간혹 유스케이스가 무엇이 아닌 ‘어떻게’를 기술하게 작성하는 경우가 있는데, 이는 그리 바람직하지 않은 모습이다. 유스케이스는 시스템이 무엇을 제공하고 액터는 무엇을 얻는가를 기술하는 방편이지 시스템을 어떻게 구축할 것인가에 대한 것은 아니다.
유스케이스 간의 관계
유스케이스와 유스케이스 사이에는 서로 밀접하게 연관되어 있어 상호간에 관계를 가지는 경우가 있다. 유스케이스는 포함(include), 확장(extend), 일반화(generalization)의 세 가지 관계 유형이 있다.
포함 관계
하나의 유스케이스가 유스케이스 내의 작업 흐름의 과정 안에 다른 유스케이스의 작업 흐름을 포함하게 하는 관계이다. 포함 관계는 <그림 5>와 같이 표기한다.
![]() |
<그림 5> 포함 관계 |
유스케이스는 액터와 시스템간의 상호 작용이나 시스템 내부의 작업 등을 기술한다. 이때 여러 유스케이스에서 비슷한 작업이 공통으로 발생하는 경우가 있을 수 있다. 이때 이렇게 공통으로 발생하는 유스케이스의 특정 부분을 하나의 유스케이스로 따로 분리하고 포함 관계를 통해 정의하는 것이 가능하다. 이는 프로그램에서 서브 루틴을 호출하는 개념과 유사하다.
포함 관계에서 유스케이스는 ‘포함하는(including) 유스케이스’와 ‘포함되는(included) 유스케이스’로 나눌 수 있다. 유스케이스는 액터가 그 작업 흐름을 기동시키는데, 포함 관계에서 ‘포함되는 유스케이스’는 액터가 아닌 ‘포함하는 유스케이스’가 작업 흐름을 기동시킨다. 그래서 ‘포함되는 유스케이스’는 ‘포함하는 유스케이스’가 없으면 제 구실을 하지 못하고 ‘포함하는 유스케이스’에 합쳐져야 제 기능을 하게 된다.
포함 관계에서 ‘포함되는 유스케이스’를 ‘포함하는 유스케이스’에 포함시킬지 여부는 ‘포함하는 유스케이스’에서 결정한다. 보통 조건절과 같은 내용이 ‘포함하는 유스케이스’에 들어가게 되고 조건절의 만족 여부에 따라 ‘포함되는 유스케이스’를 수행할 지가 결정된다. <그림 6>과 같은 유스케이스가 포함 관계의 가장 전형적인 예이다.
![]() |
<그림 6> 포함 관계의 전형적인 예 |
주문 결제 유스케이스는 액터가 결정한 결제 형태에 따라 현금 결제, 카드 결제, 포인트 결제 유스케이스 중에 하나를 포함하게 된다. 포함 관계는 유스케이스 간의 관계를 설정할 때 가장 쉽게 사용할 수 있는 관계 설정 방법이다.
확장 관계
하나의 유스케이스의 흐름이 다름 유스케이스 내의 작업 흐름의 과정에 추가되어 작업 흐름을 확장하는 관계이다. 확장 관계는 <그림 7>과 같이 표기한다.
![]() |
<그림 7> 확장 관계 |
확장 관계에서 유스케이스는 ‘확장되는 유스케이스’와 ‘확장하는 유스케이스’로 나눌 수 있다. ‘확장되는 유스케이스’가 액터와 상호작용하면서 작업 흐름을 수행하던 중 확장하는 조건이 만족하게 되면 그 만족되는 시점에서 ‘확장하는 유스케이스’가 ‘확장되는 유스케이스’에 합쳐져서 작업 흐름을 수행한다. 예를 들면 특정 작업을 수행하던 중 사용자가 도움말 버튼을 눌러서 도움말 내용을 확인하는 것 같은 작업이 전형적인 확장 관계이다.
확장 관계에서는 ‘확장하는 유스케이스’가 ‘확장되는 유스케이스’의 특정 지점으로 합쳐지게 되는데, 이 지점을 확장 지점(Extension point)이라고 한다. 확장 지점은 ‘확장되는 유스케이스’에 위치하게 되고 ‘확장되는 유스케이스’는 여러 개의 확장 지점을 가질 수 있다. ‘확장하는 유스케이스’가 ‘확장되는 유스케이스’의 어떤 확장 지점으로 확장될 것인가는 확장 관계에 표시한다. 확장 관계는 확장하는 조건과 어떤 확장 지점으로 확장될 것인가에 대한 정보를 보유한다.
유스케이스가 합쳐져서 보다 큰 작업을 한다는 점에서는 포함 관계와 확장 관계가 크게 다를 바는 없지만 그 적용되는 방법과 내용상에 있어서는 몇 가지 차이점이 존재한다.
첫째, 포함 관계는 ‘포함하는 유스케이스’가 주 흐름 유스케이스이고 ‘포함되는 유스케이스’가 주 흐름 유스케이스에 내용을 추가하는 것인 데 반해 확장 관계에서는 ‘확장되는 유스케이스’가 주 흐름 유스케이스이고 ‘확장하는 유스케이스’가 주 흐름 유스케이스에 내용을 추가하는 것이 된다.
둘째, 포함 관계에서 ‘포함되는 유스케이스’는 ‘포함하는 유스케이스’가 정상적으로 동작하기 위해서 반드시 필요한 필수 요소인 데 반해 확장 관계에서 ‘확장하는 유스케이스’는 선택 사항으로써 ‘확장되는 유스케이스’는 ‘확장하는 유스케이스’와 상관없이 독립된 기능을 수행할 수 있다.
보통 유스케이스에 내용을 추가할 때는 포함 관계나 확장 관계 중 어느 방법을 사용하더라도 큰 무리가 없다. 약간의 차이가 있다면 포함 관계로 내용을 추가하려고 할 때에는 내용 추가의 기반이 되는 ‘포함하는 유스케이스’의 내용 변경이 반드시 동반되어야 하는 데 반해 확장 관계로 내용을 추가할 때는 내용 추가의 기반이 되는 ‘확장되는 유스케이스’의 내용 변경이 불필요하다는 것이다. 따라서 이미 존재하는 유스케이스 도큐먼트 내용의 수정이 가능한지 불가능한지 여부가 포함 관계로 내용을 추가할 것인지 확장 관계로 내용을 추가할 것인지를 선택하는 기준이 될 수 있다.
일반화 관계
유스케이스 간의 일반화 관계는 객체 지향 개념에서의 상속 관계와 유사해서 자식 유스케이스가 부모 유스케이스가 가지는 속성, 작업 흐름, 확장 지점, 다른 유스케이스와의 관계 등을 모두 가진다는 의미이다. 일반화 관계는 <그림 8>과 같이 표기한다.
![]() |
<그림 8> 일반화 관계 |
자식 유스케이스는 새로운 작업 흐름이나 별도의 속성, 확장 지점, 다른 유스케이스와의 관계 등을 정의할 수 있다. 하나의 유스케이스는 여러 개의 부모 유스케이스를 가질 수 있고, 자신이 여러 유스케이스의 상위 유스케이스가 될 수도 있다.
유스케이스의 레벨
UML에 정의되어 있는 [유스케이스]의 표준에는 유스케이스에 대한 레벨이나 범위에 대한 개념이 없다. 레벨이나 범위는 유스케이스를 작성하는 과정에서 그 필요성이 자연스럽게 도출된 개념들이다. 레벨이 높은 유스케이스가 넓은 범위의 내용을 광범위하게 다루고 레벨이 낮은 유스케이스가 보다 적은 범위의 내용을 상세히 다룬다. <그림 9>는 유스케이스의 레벨에 대한 개념을 보여준다.
![]() |
<그림 9> 유스케이스의 레벨 개념 |
보통 유스케이스의 레벨은 그 유스케이스를 필요로 하는 사람에 따라 다르게 구성된다. 전체 시스템을 개괄적으로 보기를 원하는 매니저나 관리자들은 보다 높은 레벨로 구성된 유스케이스를 필요로 한다. 이들에게는 어떻게 유스케이스가 수행되는가는 주 관심 분야가 아니고 보다 높은 레벨의 관점으로 시스템을 바라보고 싶어 한다. 반면 요구사항 분석을 통해 시스템 전체의 모습을 구성해야 하는 시스템 분석가들은 보다 세부적으로 어떠한 기능을 수행하는지를 볼 수 있는 수준이 필요하다.
반면 개발자들은 요구되는 기능을 어떻게 실제로 구현할 것인지를 정의할 수 있는 수준의 유스케이스를 필요로 한다. 유스케이스를 통해 요구사항에 대한 의사소통을 하는 사람의 역할이 무엇이냐에 따라 유스케이스는 다른 레벨의 형태를 띠게 된다.
유스케이스의 레벨에 관련해서는 ‘왜’라는 물음과 ‘어떻게’란 물음이 중요한 역할을 한다. <그림 10>에서와 같이 유스케이스의 작업 흐름 내용에 대해서 ‘왜’라는 물음에 대한 답이 상위 레벨 유스케이스가 되고 ‘어떻게’라는 물음에 대한 답이 하위 레벨 유스케이스가 된다.
![]() |
<그림 10> 상위와 하위 레벌 유스케이스 |
적절한 레벨은?
유스케이스가 많이 사용됨에 따라 유스케이스가 어느 정도의 범위를 커버하도록 구성하는 것이 가장 적절한지에 대한 많은 고민이 있어왔다. 유스케이스를 작성하는 데 있어서 전형적으로 등장하는 좋지 않은 예 중에 하나가 같은 레벨의 유스케이스 간에 상세화 정도의 차이가 생기는 것이다. 같은 레벨의 유스케이스는 비슷한 정도의 범위를 비슷한 상세화 정도로 기술해야 한다.
레벨은 크게 요약(summary), 사용자 목적(user goal), 하위 기능(sub function)으로 나눌 수 있다. 사용자 목적 레벨이 요구사항을 분석하는 데 가장 적절한 수준이다. 사용자 목적 레벨에서 ‘왜’라는 질문을 통해서 내용을 정리하면 요약레벨의 유스케이스가 되고 ‘어떻게’라는 질문을 통해서 내용을 상세화하면 하위 기능 유스케이스가 된다. 사용자 목적 레벨의 유스케이스를 판단할 때 다음과 같은 정도의 기준을 사용할 수 있다.
◆ 액터가 한자리에 앉아서 한번(2분~20분)에 끝낼 수 있는 정도의 작업
◆ 작업이 완료되었을 때 액터가 자리를 뜨는데 어려움이 없는 정도
하나의 유스케이스는 사건 흐름에 보통 3~9 스텝 정도를 밟는 것이 좋다. 단 2스텝으로 끝나버린다거나 10스텝 이상으로 길어지는 것은 유스케이스를 이해하는 데 별로 좋지 않다. 만약 스텝이 길다면 다음의 예와 같은 스텝들을 하나의 스텝으로 합쳐서 스텝의 수를 조절할 수 있다.
◆ 같은 액터가 여러 스텝을 점유한 경우
◆ 액터가 사용자 인터페이스를 사용하는 부분을 여러 스텝을 통해 기술한 경우
그래도 스텝이 길다면 그 유스케이스는 너무 큰 유스케이스이거나 너무 상세화된 유스케이스인 경우가 대부분이다. 유스케이스가 크다면 여러 개의 유스케이스로 나누는 것을 고려해야 하고 너무 상세화된 유스케이스라면 ‘왜’라는 질문을 통해 레벨을 높이도록 해야 한다.
[유스케이스] 기술서
앞에서 [유스케이스]라고 하는 요구사항 분석 설계 표기법에 사용하는 여러 요소들에 대해 살펴보았다. UML이 [유스케이스]에 대해 표준으로 정의하고 있는 것은 액터나 유스케이스, 유스케이스 간의 관계와 같은 구성 요소와 그들이 서로 어떻게 연계되어 전체적인 모습을 보여주는 지와 같은 것들이다. 이것은 요구사항 분석 설계 메커니즘으로써의 [유스케이스]의 반쪽밖에 되지 않는다.
[유스케이스]의 또 다른 반쪽은 [유스케이스] 기술서라고 하는 문서의 형태로 존재하는데, 이는 표준으로 정의되어 있지 않다. 오히려 방법론 등에서 [유스케이스] 기술서를 어떠한 형태로 어떻게 작성해야 하는지를 제시하고 있다. 그래서 다양한 형태의 [유스케이스] 기술서가 정의되어 사용되고 있다. 그러면서 베스트 프랙티스가 정립되면서 표준이라 할 수 있을 정도의 [유스케이스] 기술서가 만들어 졌다.
구성 요소
[유스케이스] 기술서에는 대체로 다음과 같은 내용들이 들어가게 된다.
◆ 이름 : 유스케이스의 이름
◆ 반복 : 반복이 이루어진 횟수. 버전과 유사한 개념
◆ 액터 : 유스케이스와 관련된 액터들의 목록
◆ 범위 : 유스케이스가 어떤 수준의 범위를 다루는지에 대한 설명
◆ 레벨 : 유스케이스가 어느 레벨의 것인지에 대한 설명
◆ 요약 : 유스케이스가 어떠한 일을 하는 지를 개략적으로 설명하는 내용
◆ 주 작업 흐름 : 유스케이스가 수행하는 작업의 흐름을 여러 스텝으로 기술한 내용 중 가장 전형적으로 발생하는 것. 유스케이스가 설명하는 업무의 80% 정도가 주 작업 흐름에서 커버한다.
◆ 대안 흐름 : 주 작업 흐름을 따르는 과정에 조건에 따라 다르게 작업하는 것을 기술한 내용
◆ 예외 흐름 : 작업 흐름이 진행되는 과정에서 예외사항이 발생하였을 경우 어떻게 처리해야 하는 지를 기술한 내용
◆ 사전 조건 : 유스케이스가 제대로 작동하기 위해 사전에 만족되어야 하는 조건을 기술
◆ 사후 조건 : 유스케이스가 끝나면 어떠한 결과가 제공되는지를 기술
◆ 비즈니스 룰 : 유스케이스의 작업 흐름과 관련해서 업무 규칙에 관한 내용을 기술
◆ 사용자 화면 : 사용자 인터페이스 화면에 대한 내용
◆ 작성자 : 유스케이스의 작성자
◆ 작성일 : 유스케이스 작성일
몇 가지의 기술서 작성 양식
앞에서 여러 가지 [유스케이스] 기술서의 구성 요소에 대해서 설명했지만 일반적으로는 [유스케이스] 기술서의 구성 요소들 중 필요한 것을 선별하여 [유스케이스] 기술서 양식을 만들어서 [유스케이스]의 내용을 만드는 데 사용하게 된다. [유스케이스] 기술서의 양식은 프로젝트의 규모나 문서화를 얼마나 세세하게 할 것인지 등을 살펴보고 적합한 수준에서 결정한다.
프로젝트의 규모가 크거나 프로젝트에 대한 위험 부담이 높은 프로젝트에서는 대개 엄격한(rigorous) 방법론을 사용하는 것이 일반적이다. 엄격한 방법론에서는 산출물의 형식이나 내용의 유무를 중요하게 생각한다. [유스케이스] 기술서에도 예외가 아니어서 항목이나 내용이 많고 그 내용을 규칙에 따라 작성하도록 요구한다. 유스케이스의 엄격한 양식에는 앞서 기술한 [유스케이스] 기술서의 구성 요소가 거의 대부분 들어간다.
프로젝트의 규모가 작아서 산출물 작성의 형식에 그리 큰 비중을 두지 않는 경우나 혹은 기민한 방법론을 채택해서 산출물의 신속한 작성과 변경이 요구되는 경우는 [유스케이스] 기술서의 형식을 간략하게 사용하는 경우도 있다. <표 1>은 간략화한 양식의 예이다.
| ||||
| ||||
![]() |
| ||||
| ||||
![]() |
점증적이며 반복적인 작성 프로세스
소프트웨어 개발 방법론에서는 점증적·반복적 접근이 많이 사용되는데 [유스케이스]의 작성에도 예외는 아니다. 대부분의 [유스케이스] 작성 프로세스가 반복을 통해 점증적으로 [유스케이스]의 내용을 추가하는 방식을 취하고 있다. <그림 11>은 세 번의 반복을 통해 점진적으로 유스케이스의 항목을 추가해 나가는 유스케이스 작성 프로세스의 모습을 간략히 한 모습이다.
![]() |
<그림 11> 점진적으로 유스케이스 항목을 추가해 나가는 모습 |
초기(Initial) 단계에서는 시스템의 범위를 정하고 액터와 유스케이스를 찾는다. 여기서 액터와 유스케이스는 이름과 간략한 요약 정도만을 기술해 주면 된다. 기반(Base) 단계에서는 초기 단계에서 찾아낸 액터와 유스케이스의 내용을 보강한다. 각 유스케이스에 대해서 사건 흐름을 기술하고 선행 조건과 사후 조건을 기술한다. 상세(Elaboration) 단계에서는 유스케이스의 모든 세부 항목을 완성 시키는 단계이다. 각 유스케이스에 사건 흐름에 대해 대안 흐름과 예외 흐름을 추가한다.
코번의 12 단계 정의
writing effective use case의 저자인 코번은 유스케이스를 작성하는 12단계를 정의했다.
[1] 시스템의 범위와 경계 설정
[2] 시스템에 관계된 모든 액터 찾기
[3] 액터가 시스템을 통해 얻으려고 하는 목적들 찾기
[4] 각 액터에 대한 최상위 유스케이스(summary use case) 설정
[5] 최상위 유스케이스들에 대한 정제 작업(시스템 범위의 재확인)
[6] 상세 작업을 할 유스케이스 선택
[7] 이해 관계자와 그들의 목적, 선행 조건, 후행 조건 등을 뽑아냄
[8] 주 성공 작업 흐름 작성
[9] 대안 흐름과 예외 흐름 찾기
[10] 대안 흐름과 예외 흐름 작성
[11] 복잡한 스텝을 하위 유스케이스로, 자잘한 스텝들은 모아서 하나로 합치는 작업 수행
[12] 유스케이스 조절 작업(읽기는 쉬운지, 구색은 갖췄는지, 이해 관계자는 만족하는지) 수행
코번의 12단계도 앞서 설명한 작업 절차와 그리 큰 차이는 보이지 않는다. 중요한 것은 반복적으로 점증적으로 [유스케이스]를 작성해 나간다는 것이다.
UML을 제대로 사용하려면 이것은 기억하자
[유스케이스] 모델과 [유스케이스] 기술서 등 [유스케이스]와 관련한 여러 가지를 살펴보았다. 이제는 [유스케이스]와 관련해서 유의해야 할 점을 짚어 보기로 하자.
액터와 유스케이스의 연결
UML 표준에는 액터와 유스케이스의 연결에 단순한 직선 연결만을 사용하고 있는데 화살표를 사용해서 나름의 의미를 부여하는 경우도 있다. 다음은 화살표 사용의 몇 가지 사례이다.
◆ 주요 액터가 유스케이스를 기동하는 경우에만 액터에서 유스케이스 쪽으로 화살표 머리 사용
◆ 주요 액터가 유스케이스를 기동하거나 유스케이스가 보조 액터를 기동하는 경우 기동하는 쪽으로 화살표 머리 사용.
◆ 단 방향 커뮤니케이션에만 화살표 머리 사용. 기대되는 응답이 없는 경우에 사용한다(예 : 프린터로 명령을 보내는 경우, 정부 기관에 내용을 통보하는 경우)
[유스케이스] 다이어그램에서 화살표를 사용할 때에는 데이터의 흐름이 아니라 커뮤니케이션의 기동 방향을 보여주는 데 사용하는 것이 좋다. 데이터는 보통 액터와 유스케이스 사이에 양방향으로 흐르는 것이 일반적이기 때문에 데이터의 흐름으로 화살표를 사용하게 되면 양방향 화살표가 되게 되고 이것은 다이어그램을 어지럽히는 원인이 된다.
전통적인 실수들
[유스케이스]를 작성하는 데 있어서 다음과 같은 실수가 자주 발생한다.
◆ 액터가 없는 유스케이스, 시스템이 없는 유스케이스
액터와 유스케이스는 반드시 서로 연결되어 있어야 한다. ‘포함되는 유스케이스’나 ‘확장하는 유스케이스’의 경우도 포함 또는 확장되어 액터와 연결된다. 간혹 혼자 동떨어져 있는 유스케이스가 있는 시스템이 보이기도 하는데 이는 잘못 작성된 것이다.
◆ 사용자 인터페이스의 내용을 너무 상세히 담고 있는 [유스케이스]
[유스케이스]는 기능적 요구사항을 담는 것이기 때문에 사용자 인터페이스의 상세한 내용은 담지 않는다. 다만 사용자 인터페이스를 상세하게 설명한 문서에 대한 참조 정도를 추가하면 된다.
◆ 너무 낮은 레벨의 [유스케이스]
구현에 대한 상세한 내용이 담겨 있는 [유스케이스]는 적절하지 않다. [유스케이스]에 소스코드 레벨의 설명이 들어 있는 경우가 간혹 있는데 ‘왜’라는 물음을 통해 상위레벨의 [유스케이스]로 만드는 것이 좋다.
◆ 전산인의 언어를 사용한 유스케이스
[유스케이스]는 요구사항을 기술하고 그것을 통해 여러 관여자 들과 의사소통을 하기 위해 만드는 것이다. [유스케이스]에 사용하는 용어는 많은 사람이 이해할 수 있도록 보편적인 용어를 사용해야 한다.
◆ 애플리케이션 관점의 유스케이스
유스케이스는 액터의 관점에서 기술해야 한다. 시스템의 관점에서 기술한 유스케이스는 적절하지 않다.
◆ ‘~해야 한다’ 식의 표현
요구사항을 기술하는 전통적인 방법에서는 ‘시스템은 ~해야 한다’는 식의 표현이 자주 등장한다. 이러한 표현을 [유스케이스]에서는 사용하지 않는 것이 좋다. 만약 고객의 요구로 ‘~해야 한다’는 식의 표현을 넣어야 한다면 [유스케이스]의 요약 부분에 넣는 것이 좋다. 작업 흐름 부분에는 ‘~해야 한다’가 아닌 ‘~한다’라는 표현을 사용해야 한다.
유스케이스 작성에 대한 10가지 잘못
[1] 다른 형태의 요구사항 문서는 만들 필요가 없다. [유스케이스]면 요구사항을 충분히 반영할 수 있다.
아니다. 요구사항 문서는 요구사항을 가장 잘 반영할 수 있는 형태의 문서로 만들어야 한다. 데이터베이스 설계에 대한 요구사항은 ER모델이 적합하고, 화면 구조에 대한 요구사항은 그래픽이 가미된 문서가 더 적합하다.
[2] 읽는 사람이 [유스케이스]의 목적에 대해 이해하기 힘들게 한다. [유스케이스]의 이름을 지을 때 ‘작업하다’, ‘처리하다’와 같은 말을 사용하여 혼란스럽게 한다. 만약 읽는 사람을 혼란스럽게 하는 데 성공했다면 [유스케이스]를 실제로 구현할 때 어떻게 해도 상관없을 것이다.
[유스케이스]를 이용해서 효과적으로 소프트웨어 시스템을 구현하기 위해서는 명확하게 [유스케이스]를 작성할 필요가 있다. 간혹 어떻게 [유스케이스]를 작성해야 하는지 모르는 경우에 이렇게 처리하는 경우가 있는데 좋지 않은 모습이다.
[3] [유스케이스]의 범위에 대해 혼란스럽게 한다. 범위는 어차피 점점 퍼져나갈 것이고 나중에 리펙토링을 하면 된다. 사용자는 어차피 생각을 계속 바꿀 것인데 왜 성가시게 범위를 미리 확정하겠는가?
[유스케이스]는 만들려고 하는 시스템이 어떠한 범위를 다루는지를 표현하는 것에도 사용된다. 시스템의 범위를 명확히 하고 그것을 여러 관여자가 충분히 이해할 수 있도록 [유스케이스]를 작성해야 한다.
[4] [유스케이스] 기술서에 비기능적 요구사항과 사용자 인터페이스 디테일을 포함시킨다.
유스케이스의 작업 흐름에 사용자 인터페이스에 대한 세부 내용을 포함시키면 작업 흐름이 늘어나게 된다. 사용자 인터페이스를 요약한 내용을 추가하면 되지 상세한 내용까지는 포함시킬 필요가 없다.
[5] 초기 [유스케이스] 다이어그램에 포함 관계와 확장 관계를 많이 사용한다. 그러면 유스케이스를 작은 단위의 것으로 나눌 수가 있다.
초기 버전의 유스케이스는 상위레벨의 유스케이스를 작성하고 반복을 거치면서 보다 상세화한 유스케이스를 작성하는 것이 좋다. CRUD를 처리하는 유스케이스가 대표적인데, 초기에는 ‘관리하다’라는 유스케이스로 하나로 만들고 이후에 반복을 통해 ‘생성’, ‘조회’, ‘수정’, ‘삭제’ 유스케이스로 세분화한다.
[6] 비즈니스 룰을 정의하는 것에는 관여하지 말라.
비즈니스 룰을 만들고 사용하는 것은 사용자이지만 그것을 산출물로 표현하도록 하는 것은 매우 중요하다. 룰 자체를 만드는 것에는 관여할 필요가 없지만 그것을 [유스케이스]를 통해 표현하도록 독려해야 한다.
[7] [유스케이스]의 작성에 도메인 전문가를 관여시키지 말라. 그들은 질문이나 해댈 뿐이다.
[유스케이스]는 요구사항에 대한 표준 표기법인데, 소프트웨어 시스템에 대한 요구사항을 가장 잘 알고 있는 것은 도메인 전문가이다. 물론 이들이 작업을 성가시게 할 수도 있지만 좋은 결과를 내기 위한 고통이라 생각해야 한다.
[8] 만약 사용자를 [유스케이스] 정의에 관여시킨다면 그냥 그래라. 왜 사용자와의 미팅을 준비하는 데 골머리를 썩힐 것인가? 많은 양의 문서나 만들게 되고, 어쨌든 그들은 계속 마음을 바꾸게 될 것이다.
될대로 되라는 식의 태도는 좋지 않다. 사용자에게 [유스케이스]를 충분히 이해시키고 [유스케이스]를 통해 효과를 볼 수 있도록 노력해야 한다.
[9] [유스케이스]를 한 번에 아주 상세하게 만들어라.
반복적으로 점증적으로 [유스케이스]를 작성하는 것이 좋다.
[10] [유스케이스]를 검증하거나 평가하지 말라. 재작업이나 만들어 낼 뿐이다.
반복적으로 점증적으로 작성하고 중간중간 계속 사용자나 도메인 전문가의 피드백을 받아야 한다.
아름다운 표현 양식이 되길 바라며
요구사항을 수집하는 일은 오래 걸리거나, 잘못된 것을 기록하거나, 발생하지 않을 일을 추측하거나, 시간에 맞춰 허겁지겁 끝내는 등과 같은 결과를 초래하는 경우가 많다. 이는 요구사항 수집이 비생산적인 경로를 거치거나, 요구사항 수집을 무시하거나, 요구사항 수집 자체만을 위해 매달리거나, 요구사항을 한 사람이 결정하기 때문에 발생한다.
[유스케이스]는 이러한 요구사항 수집에 사용하기 좋은 방법 중 하나이다. [유스케이스]의 표준을 따라 보편화된 방법으로 요구사항을 기술하면 보다 많은 사람들이 사용할 수 있을 것이다. 물론 표준에 대한 준수 여부보다는 [유스케이스]의 내용을 어떠한 생각을 가지고 채워 넣었느냐가 더욱 중요하다.
UML은 단순한 표기법에 지나지 않지만 아주 좋은 표기법임에는 틀림없다. 마치 한글처럼. 아름다운 우리말을 한글이 잘 표현하듯이 소프트웨어 개발에 대한 여러분의 멋진 생각들을 UML을 통해 잘 표현해 보기를 바란다.@
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
AOP (Aspect Oriented Programming) (0) | 2008.08.03 |
---|---|
AOP (Aspect Oriented Programming) (0) | 2008.08.03 |
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드 (0) | 2007.09.27 |
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
2007. 9. 27. 21:30 IT 자료/소프트웨어 공학
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드
김상훈 (동명정보대학 정보기술 연구원) 2005/03/31
연재순서 1회. 가능성·확장성 품고 등장한 UML 2.0 2회. 초보자를 위해 다각도로 살펴본 UML 3회. 바로 알고 제대로 쓰는 UML 실전 모델링 4회. 닷넷 환경에서 UML 툴 활용 가이드 5회. 표준을 넘나드는 UML의 적절한 사용 |
하지만 IDE와 통합된 케이스 도구는 코드의 자동 생성 등의 많은 편리한 도구를 제공한다. IDE와 통합된 케이스 도구는 UML이라는 것에 너무 얽매이지만 않고 자유롭게만 사용한다면 아주 훌륭한 프로젝트 도우미가 될 수 있다.
전통적으로 MS의 개발 플랫폼에서 사용하는 개발 도구는 MS가 100% 독점하다시피 해 왔다. STL이나 MFC를 개발하거나 사용하는 도구는 거의 비주얼 C++가 독점적이었고, COM 기반의 개발을 위해 사용되는 도구는 거의가 비주얼 베이직이었다(COM 개발을 위해 비주얼 C++를 사용하는 경우도 많이 봤지만 그 당시 이슈가 되던 RAD와는 거리가 먼 환경이었다). 물론 볼랜드의 델파이 등을 많이 사용하기도 했지만 MS의 막강한 개발 도구 비주얼 스튜디오를 넘기에는 벅차 보였다.
닷넷 환경이 발표되고, 닷넷이 산업계에서 서서히 자리를 잡아가자 닷넷 개발 도구의 필요성이 절실해 졌고, 당연히 MS의 비주얼 스튜디오 닷넷이 닷넷 개발 도구의 최강자 자리를 당연히(!) 차지했다. 사실, 비주얼 스튜디오 닷넷이 없으면 닷넷 개발이 불가능하다고 생각하는 사람들도 많다.
볼랜드가 C# 빌더 등의 닷넷 환경을 지원하는 도구를 내 놓았고, 기타 여러 벤더들이 제품을 출시했지만 MS의 아성을 무너트리기에는 역부족이다. 비주얼 스튜디오 닷넷은 닷넷 환경이 존재하는 한 닷넷 기반 IDE의 최강자로서 그 자리를 내놓지는 않을 듯 하다.
그렇다면 비주얼 스튜디오 닷넷에는 약점이 없을까? 아니다, 분명히 약점은 존재한다. 그것도 아주 커다란, 치명적인 약점이 있다. MS는 닷넷 환경을 분명한 객체지향 개발 환경(닷넷 환경에서의 CBD는 객체지향이 없이는 존재할 수 없다)이라고 했다. 객체지향 개발 환경이라면 객체지향 설계 도구가 없다면 그 활용 범위가 반감될 수밖에 없는데, 비주얼 스튜디오 닷넷 엔터프라이즈 아키텍트 버전에 포함된 비지오가 어느 정도 그런 기능을 해 주긴 하지만, 다른 객체지향 개발 도구인 로즈나 볼랜드 투게더(이하 투게더) 등의 편리함과 기능성에는 결코 미치지 못한다.
설계 도구와 개발 도구의 진정한 결합. 이상적인 환경이지만 사실 구현하기 어려운 개발 환경임에 틀림없다. 비주얼 스튜디오 닷넷은 분명 막강한 개발 환경이고, 비주얼 스튜디오 닷넷을 사용하면서 투게더 또는 로즈 같은 개발 도구를 같이 사용할 수는 없을까 하는 생각을 누구나 한번쯤은 해 보았을 것이다. 정말 그럴 수 있을까? 대답은 "물론 있다"이다. 로즈와 투게더는 비주얼 스튜디오 닷넷 XDE를 제공한다(물론 구입해야 한다).
래쇼날 로즈 2000 XDE
객체지향 모델링 도구 중 가장 유명하며, 많이 사용되는 도구인 로즈는 2002년 MS의 비주얼 스튜디오 닷넷에 애드인되어 사용될 수 있는 ‘래쇼날 로즈 2000 XDE for 비주얼 스튜디오 닷넷’을 발표했다(어찌된 일인지 아는 사람도 별로 없고 사용하는 사람은 더더욱 없다). 로즈 XDE를 가지고 있다면 그 자리에서 설치해 보기를 바란다. 물론 설치하는 시스템에 비주얼 스튜디오 닷넷이 설치되어 있어야 한다.
![]() |
<화면 1> 로즈가 설치된 비주얼 스튜디오 닷넷 2003 |
로즈를 처음 설치하고 나면 처음엔 아무것도 없다. 도구상자에 뭔가 추가된 것도 아니고, 특별히 뭔가가 설치되었다는 느낌을 받을 수가 없는데(굳이 뭔가 설치되었다는 느낌이라면 아마 비주얼 스튜디오 닷넷의 실행 속도가 눈에 띄게 느려졌다는 느낌이 될 것이다) 솔루션 탐색기를 눈여겨 보면 평소에 볼 수 없던 아이콘이 하나 생겨있음을 알 수 있다. 그 아이콘을 주저 없이 클릭해 보자.
![]() |
<화면 2> 추가된 동기화 아이콘 |
동기화 아이콘을 클릭하면 로즈와 비주얼 스튜디오 닷넷이 동기화되어 mdx 파일을 생성한다. 그리고 Model Explorer 창이 새로 생기고 프로젝트에 포함되어 있는 개체들을 탐색할 수 있게 해준다.
![]() |
<화면 3> 로즈 XDE를 이용하여 Iterator 패턴을 디자인한 모습 |
로즈를 사용하여 모델링을 어느 정도 마쳤으면, 다시 동기화 버튼을 눌러 순 공학할 수 있다.
![]() |
<화면 4> 로즈가 생성한 C# 코드 |
감동의 기능
[1] 너무 깔끔한 코드를 생성하고 닷넷 환경에서 권장하는 주석 내용들을 그대로 생성해준다. 다른 도구들은 생성한 코드의 indentation이 잘 되지 않거나 참조한 라이브러리의 네임 스페이스를 제대로 표시하지 않는 경우가 많은데, 그런 단점이 사라졌다.
[2] 참조한 라이브러리의 개체들을 모두 설계에 사용할 수 있게 해준다. 다른 모델링 도구들은 기본으로 포함되거나 직접 작성한 개체들만이 사용가능 한 경우가 대부분인데, 최상의 도구다운 기능을 보여준다.
[3] 깔끔하고 예쁜 출력을 지원한다. 다른 설계 도구의 경우 한 페이지 또는 두 페이지에 깔끔하게 출력할 수 있는 기능에 대한 지원이 부족한데, 깔끔하고 예쁘장한 산출물을 만들 수 있도록 도와준다.
[4] ASP.NET/ASP/Service Page 들에 대한 설계를 지원한다. Web Presentation Pattern을 응용한 설계가 필요할 때 아주 유용하다.
단점이라면, C#으로 작성한 메쏘드의 수정이 아주 불편하다. 또한, RUP를 너무 강조하는 경향이 있어 닷넷의 빠른 개발과는 어울리지 않는 부분이 엿보이고, 일일이 동기화를 해 주어야 코드와 설계가 연동이 되는데, 에러를 자주 발생하여 동기화가 되지 않는 경우가 빈번히 발생한다.
볼랜드 투게더
비주얼 스튜디오 닷넷에서 다른 유명한 설계 도구인 투게더를 사용할 수 있다. 투게더 역시 로즈와 마찬가지로 비주얼 스튜디오 닷넷에 애드인되어 설치된다. ‘볼랜드 투게더 for 비주얼 스튜디오 닷넷 2.0’을 설치하면 비주얼 스튜디오 닷넷에 투게더 VS.NET Model View라는 창이 생성된다.
![]() |
<화면 5> 투게더 for 비주얼 스튜디오 닷넷 Model View |
또한 솔루션 탐색기에 ModelSupport라는 폴더가 생성되고 폴더 내부에는 .txvpak이라는 확장자를 가지는 모델 파일이 생성된다. 이 파일을 더블클릭하여 모델링 도구를 사용하여 설계할 수 있는 설계 창을 열 수 있다.
![]() |
<화면 6> 투게더를 사용해서 Iterator 패턴을 디자인 한 모습 |
투게더는 로즈와 달리, 코드의 실시간 생성을 지원한다. <화면 6>에서 보이는 클래스 아이콘을 더블클릭하면 코드를 곧 바로 생성하게 된다. 코드를 수정하건, 설계를 수정하건 간에 설계 또는 코드의 수정 사항이 즉시 상호간에 적용되게 되어있다.
감동의 기능
[1] 필자가 투게더를 사용해 보고 가장 감동적이었던 기능은 시퀀스 다이어그램을 실시간으로 생성해 주는 기능이었다. 메쏘드가 특정 객체들을 사용하도록 구성되었으면, 투게더는 그 메쏘드의 시퀀스 다이어그램을 아주 믿을만한 수준으로 자동 생성해 준다. <화면 7>은 Petshop 3.0의 AccountController 클래스의 CreateAccount 메쏘드의 시퀀스를 자동 생성한 것이다.
![]() |
<화면 7> 자동 생성한 시퀀스 다이어그램 |
[2] 여러 디자인 패턴에 기반한 설계를 지원한다(로즈 역시 이 기능을 지원한다). GOF 디자인 패턴에 기반하여 설계를 하고자 하면 투게더는 디자인 패턴에서 각 객체들의 역할을 보여주며 각 역할을 하는 객체를 추가하고 삭제하는 Node by Pattern 도구를 지원한다. 투게더는 디자인패턴에 기반한 설계를 쉽고 오류 없이 할 수 있도록 도와주며 특히 디자인 패턴을 공부하는 사람에게 아주 유용한 도구가 될 수 있다.
단점이라면 생성된 코드가 그다지 깔끔하지 않아 재 정렬을 해줘야 한다는 점 등이다. 앞에서 설명한 두 가지 도구의 치명적인 단점이 하나 있다. 닷넷 환경에서는 실행할 때 참조되는 라이브러리를 복사하고 실행시 참조하므로 개발 중 라이브러리를 수정하고 다시 컴파일하여도 누군가 파일을 사용 중이기 때문에 덮어쓸 수 없다는 메시지를 절대로 보여주지 않는다. 하지만 앞의 두 도구는 모델링에 사용하고 있는 참조되는 라이브러리를 ‘물고’있기 때문에 참조하는 프로젝트를 종료하고 컴파일한 후 다시 비주얼 스튜디오 닷넷을 실행하여 계속 진행해야 한다.
그리고 전통적으로 닷넷 개발에서는 RUP 같은 개발 방법론이 사용되지 않아, 만약 UML을 그렇게 많이 사용하지 않는 개발자라거나 다른 개발 방법론을 준수하는(MSF 등의) 프로젝트라면 사용할 수 있는 다이어그램은 클래스 다이어그램뿐이고, 너무 많은 도구를 제공함으로서 개발에 혼란이 오며, 비주얼 스튜디오 닷넷 자체가 너무 느려져서 개발자의 '성질'에 나쁜 영향을 끼칠 수 있다는 것이다.
비주얼 스튜디오 닷넷 2005에 포함된 모델링 도구
MS도 닷넷 환경이 객체지향 환경이고, 객체를 모델링 할 수 있는 통합된 개발 도구가 필요하다는 것을 모를 리가 없다. 그래서 MS는 비주얼 스튜디오 닷넷의 차기 버전인 비주얼 스튜디오 닷넷 2005에 그런 모델링 도구를 추가했다(전체적으로는 투게더와 비슷한 모습이고, 필자가 현재 기사를 작성하고 있는 시점에서는 클래스 다이어그램 기능 이외의 기능은 들어있지 않다).
비주얼 스튜디오 닷넷 2005의 클래스 다이어그램 기능을 알아보자. 비주얼 스튜디오 닷넷 2005는 특별히 이전 버전과 비교해서 달라진 기능이 없다. 웹 프로젝트를 다른 프로젝트와 구분해서 생성하는 정도가 외관상으로 볼 때 달라진 기능이라 할 것이다. 비주얼 스튜디오 닷넷에서 클래스 다이어그램을 그리고 실시간으로 변경될 수 있는 기능을 사용하려 한다면 이전 버전에서 새 항목 추가 메뉴를 선택하는 것과 같이 한다. 새 항목 추가 다이얼로그 박스를 유심히 살펴보면 클래스 다이어그램이라는 항목 아이콘이 보이고 그 항목을 사용하여 클래스 다이어그램을 작성할 수 있다.
![]() |
<화면 8> 비주얼 스튜디오 닷넷 2005의 새 항목 추가 다이얼로그 박스 |
![]() |
<화면 9> 비주얼 스튜디오 닷넷 2005를 사용해서 Iterator 패턴을 디자인 한 모습 |
장점
[1] 아무래도 비주얼 스튜디오 닷넷에 애드인된 것이 아닌 빌트인된 모델링 도구이다 보니 애드인된 도구보다는 강한 결합성을 가진다. 빌트인되었을 때의 가장 큰 기대점은 아무래도 성능적인 측면인데 아직 베타 버전이기에 평가 내리기가 이른 듯 하다. 하지만 꽤 만족할만한 성능을 보여주고 있으며, C# 또는 비주얼 베이직 닷넷에 종속적인 멤버들만을 포함하므로 닷넷 개발에 어울리는 도구가 될 듯 하다.
[2] 비주얼 스튜디오 닷넷에 포함된 도구이다 보니 닷넷 개발에 가장 어울리는 코드를 생성하고 다른 도구들과 통합하여 사용할 수 있다. 닷넷에 추가된 수많은 새로운 개념들과 도구들을 사용할 수 있다.
[3] 비주얼 스튜디오 닷넷에는 지면 관계상 다 소개할 수는 없지만 모델링에 관계된 많은 새로운 도구들이 추가되었다. XML 디자인이나 데이터베이스 디자인, 배포 디자인까지 비주얼 스튜디오 닷넷에서 할 수 있다. 이런 기능들은 평소 비주얼 스튜디오를 사용하던 개발자들에게 아주 친숙한 환경을 제공해 줄 수 있다.
단점이라면, 그 외에 아무것도 없다는 것이다. 또한, 현재 베타 버전에서는 다른 라이브러리에 포함된 개체들을 클래스 다이어그램에 포함하는 인터페이스가 상당히 불편하다. 이는 개선되어야 할 점이다. 사실 투게더나 로즈같은 훌륭한 도구들을 사용하던 입장에서 비주얼 스튜디오 닷넷 2005의 설계 도구를 테스트 하는 입장에서는 전혀 새로울 것도 없고 감동적일 것도 없다.
또한 MS가 자사의 객체지향 개발 방법론을 연구하고 있다는 소문이 풍문에 들려오는 것을 보면, 정식 제품에는 다른 도구가 추가될 지도 모르고, 로즈나 투게더 같은 도구 정도의 많은 기능은 아니더라도 다른 많은 도구들이 추가될 것으로 보인다.
독이 될 수도 갈라드리엘의 별이 될수도
UML은 좋은 도구다. 하지만 대부분의 개발 팀에는 도움이 되기보다는 방해가 되기 일쑤다. UML에는 너무나 많은 것이 있고, 다 활용하기는 벅차고, 그렇다고 사용하지 않기에는 또 뭔가 빠진 듯한 느낌이 드는 것이 그것이다. 늘 절제하는 마음으로 UML을 사용한다면, UML은 아주 좋은 도구가 된다.
필자는 항상 이런 얘기를 한다. "로즈가 설치되어 있는 책상 위에는 항상 연필과 지우개, 그리고 종이가 있어야 한다" 특히 개발자의 입장에서는 UML이라는 도구는 독이 될 때는 한 모금에 사람을 죽일 수도 있는 치명적이 독이 될 수도, 또는 길을 안내해주는 갈라드리엘의 별이 될 수도 있다.@
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
AOP (Aspect Oriented Programming) (0) | 2008.08.03 |
---|---|
[UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」 (0) | 2007.09.27 |
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
[UML 제대로 알기] ① 가능성·확장성 품고 등장한 UML 2.0 (1) | 2007.09.27 |
2007. 9. 27. 21:29 IT 자료/소프트웨어 공학
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링
개발 프로세스에 따른 UML 실전 모델링
고재현 2005/03/26
연재순서 1회. 가능성·확장성 품고 등장한 UML 2.0 2회. 초보자를 위해 다각도로 살펴본 UML 3회. 바로 알고 제대로 쓰는 UML 실전 모델링 4회. 닷넷 환경에서 UML 툴 활용 가이드 5회. 표준을 넘나드는 UML의 적절한 사용 |
이번 글에서는 지금까지 UML을 이용하여 소프트웨어 개발을 수행하면서 느꼈던 개념상의 모호함과 모델링 시 주의할 점에 대해 살펴보고자 한다.
약 7년 전 필자는 UML에 관하여 세미나를 하려고 어느 업체를 방문한 적이 있었다. 세미나를 막 시작하려고 하는 순간 어느 분께서 'UML이 이번에 새로 나온 XML의 한 종류인가 보죠?'라고 질문을 했다. 과연 이 난관을 어떻게 헤쳐 나가야 할지 막막한 순간이 UML에 관한 이야기를 하려고 하면 지금도 떠오른다.
UML이 우리나라에 처음 소개되던 시기에는 많은 분들이 객체지향이나 모델링 언어에 대한 개념이 일반적이지 않았다. 하지만 약 7년이 지난 지금은 소프트웨어 개발을 하는 대부분의 종사자들은 UML이라는 것이 무엇이고 어디에 쓰는 것인지 알고 있다. 또한 소프트웨어를 개발하기 위해서는 적어도 UML 다이어그램 몇 개 정도는 그려줘야 할 것 같은 생각을 갖고 있다. 많은 인식의 변화가 있었지만 지금 이 순간에도 여전히 UML이라는 것을 제대로 활용하여 소프트웨어를 개발하고 있는지 제대로 알고 있는지는 의문을 갖지 않을 수 없다.
UML과 모델 그리고 산출물
UML과 모델, 산출물은 비슷한 것 같지만 실은 아주 다른 개념이다. 우리가 소프트웨어라는 것을 개발하기 위해 '무엇을 만들 것인가?'라는 질문에 답하기 위해서는 대상이 되는 문제영역을 정확히 알 필요가 있다. 소프트웨어 개발팀 혹은 개발자는 문제영역에 대하여 정확하게 이해하기 위한 가장 좋은 방법은 모델을 통하는 것이다. 모델은 문제영역의 현실을 단순화시킴으로써 우리가 만들고자 하는 시스템을 더 잘 이해할 수 있게 한다.
『The UML User Guide』에 의하면 모델링을 통해 우리는 다음과 같은 4가지 목적을 얻을 수 있다고 한다.
◆ 모델은 시스템을 현재 또는 원하는 모습으로 가시화하도록 도와준다.
◆ 모델은 시스템의 구조와 행동을 명세화할 수 있게 한다.
◆ 모델은 시스템을 구축하는 틀을 제공한다.
◆ 모델은 우리가 결정한 것을 문서화 한다.
즉, 복합한 시스템에 대해 모델을 만드는 이유는 그러한 시스템을 전체적으로 이해할 수 없기 때문이다. UML은 앞에서 언급한 4가지 목적에 충실히 부합하기 때문에 소프트웨어를 개발함에 있어 모델링 언어로 UML을 이용한다.
UML 다이어그램이 산출물인가?
필자는 어느 프로젝트의 개발 프로세스 멘터링를 하기 위해 한 업체를 방문한 적이 있었다. 그 곳에서 도착하여 간단한 미팅을 한 후 가장 먼저 요구했던 정보는 고객과 합의한 활동과 산출물의 목록이었다. 그 문서에는 역시 예상대로 요구사항 산출물에 '유스케이스 다이어그램'이라는 것이 있었고 분석 산출물에 '클래스 다이어그램'이라는 것이 들어 있었다. 이외 여러 부분에 'XXX 다이어그램'이 눈에 띄었다.
UML 다이어그램이 산출물이 될 수 있는가? 결론적으로 말하자면 UML 다이어그램은 산출물이 아니다. 나중에 자세히 설명하겠지만 산출물의 한 종류가 모델이고 모델을 표현하기 위한 수단 중에 하나가 UML 다이어그램이다.
예를 들어 UML의 클래스 다이어그램을 생각해 보자. 다양한 종류의 산출물은 그 산출물이 표현하고자 하는 정보를 보여주기 위해 UML 다이어그램을 이용한다. 유스케이스 실현(Realization)의 VOPC(View of Participating Classes)에서도 사용하고 비즈니스 조직을 표현하고자 할 때도 클래스 다이어그램을 사용할 수 있다. 또한 아키텍처 메커니즘을 표현하고자 할 때도 클래스 다이어그램을 이용한다. 유스케이스 다이어그램의 경우도 비즈니스 유스케이스 모델을 표현할 때도 쓰이고 시스템 유스케이스 모델을 표현할 때도 쓰인다. 다양한 산출물에 UML 다이어그램을 쓴다.
요구사항에서 혹은 분석/설계에서 산출물로 클래스 다이어그램이라고 명시해 놓으면 과연 어떤 클래스 다이어그램인지 알 수 있을까? 또한 시퀀스 다이어그램이 산출물 목록에 버젓이 들어있다면 그 다이어그램은 과연 어떤 정보를 표현하려고 하는 다이어그램인지 알 수 없다. 다이어그램은 산출물의 의도를 표현하기 위해 사용하는 하나의 표현도구이다. 산출물은 절대로 아니다.
우리의 목적은 산출물이다
앞에서 UML은 산출물이 아니며 모델은 산출물의 한 종류라는 것의 이야기했다. 그렇다면 산출물을 무엇을 의미하는가? 일반적으로 산출물이라는 것은 종이 형태의 문서로 알고 있다. 하지만 산출물은 프로세스를 통해 프로젝트 기간 동안 만들어지는 의미를 갖는 모든 것을 일컫는다. 그 중 하나가 모델이며 실행 가능한 바이너리 형태의 컴포넌트, 문서, 소스코드, 스크립트 등이 해당한다. 산출물(Artifact)의 정의를 보면 다음과 같다.
산출물은 어떤 정보의 일부로서 1) 프로세스를 통해 만들어지고 변경되고, 사용되며 2) 책임영역을 정의하며 3) 버전컨트롤의 대상이 된다. 산출물은 모델, 모델요소, 또는 문서 등이 될 수 있으며 문서는 다른 문서의 일부분으로 포함 될 수 있다(A piece of information that: 1) is produced, modified, or used by a process, 2) defines an area of responsibility, and 3) is subject to version control. An artifact can be a model, a model element, or a document. A document can enclose other documents).
◆ 모델(model) : 유스케이스 모델, 분석 모델, 설계 모델과 같이 다른 산출물을 포함하는 형태를 갖는 산출물
◆ 모델 요소(model element) : 다른 산출물 내부에 포함되어 있는 산출물로 예를 들면 유스케이스 모델 안의 유스케이스, 액터와 설계 모델 내부의 설계 클래스, 설계 서브시스템 등과 같은 산출물
◆ 문서(document) : 문서로 존재하는 산출물로 비즈니스 케이스, 소프트웨어 아키텍처 문서 등과 같은 산출물
◆ 소스코드나 실행 가능한 것(컴포넌트) 등
<그림 1>은 산출물과 모델 그리고 UML과의 관계를 클래스 다이어그램으로 표현한 것이다.
![]() |
<그림 1> 산출물의 종류와 UML간의 관계 |
모델링은 개발기간을 늘이는 원흉?
필자는 지금까지 여러 프로젝트에서 직접 개발에 참여하기도 했고 컨설팅 또는 멘터링 형태로 참여하면서 사람들로부터 많은 질문을 받아왔지만 그 중에 가장 많이 하는 질문은 “우리 프로젝트에 UML이 꼭 필요하겠습니까? 프로젝트 규모가 좀 작으면 UML을 적용하지 않아도 괜찮지 않을까요?”라는 것과 “UML을 적용하면 개발이 좀 늦어지지 않겠습니까?”라는 두 가지 질문이 대표적이다.
우선 첫 번째 질문의 의미를 생각해 보자. 프로젝트 규모가 작으면 UML을 굳이 적용하지 않고 두어 명 개발자들이 그냥 뚝딱뚝딱 시스템을 만들면 되지 않을까 하는 것이다. 필자도 비슷한 생각으로 모델링을 하지 않고 프로젝트를 진행해 본적이 있었다. 개발자 3명이 기능 수 약 100개 정도의 시스템을 개발한 적이 있었는데, 작고 간단한 시스템이었으므로 순진한 생각에 그냥 테이블 정도만 정리해 놓고 코딩부터 시작하면 쉽고 금방 될 줄 알았다.
하지만 상황은 그렇게 호락호락하지 않았다. 용어와 기능부터 명확히 정의되지 않았고, 시작부터 개발자간의 서로 다른 이해수준은 프로젝트를 암울하게 만들었다. 어렴풋한 이해를 바탕으로 만들어지는 코드는 만들고 나서 뜯어고치는 코드가 더 많아 졌고 비즈니스 컴포넌트간의 인터페이스로 수시로 어긋났다. 결국 간단하게나마 모델을 만들면서 진행하기로 했고 모델링 시간 약간 줄이려고 하다가 우왕좌왕한 만큼 시간을 허비한 결과로 나타났다. 꼭 UML이 아니더라도 어떤 형태로든지 모델링은 해놓았어야 했고 그것이 업계 표준인 UML로 했더라면 더 좋지 않았을까 하는 후회가 든다.
혼자 만들더라도 역시 UML로 모델링을 하는 것이 개발하는 중에도 좋고 개발하고 난 뒤를 생각해봐도 반드시 필요하다는 생각이다. 개발을 마치고 난 뒤에 누군가 그 시스템을 유지보수 해야 한다면 전 개발자가 UML을 이용하여 만들어 놓은 모델을 보고 아마 감사하게 생각 할 것이다. 또 개발하고 있는 순간에도 몇 명밖에 없지만 그 사람들끼리 의견 교환이나 문제 영역에 대한 공통적인 이해를 돕기 위해서도 필요하다. 혼자 개발하더라도 생각이 정리가 잘 안되면 UML로 아이디어를 정리하는 판에 다른 사람과 생각을 맞추는데 필요가 없겠는가?
“UML을 적용하면 개발 기간이 늦어진다”. 어떻게 보면 약간 황당할 정도의 이야기임에 틀림없다. UML 때문에 개발기간이 늘어나는 것이 아니라 익숙지 않은 UML을 모델링 언어로 선택함으로써 배우는 기간이 더 늘어나는 것이 정확한 의미가 아닐까 싶다. 심지어 어떤 프로젝트 매니저는 개발은 그냥 개발대로 나가고 산출물은 산출물대로 만들어 나가서 나중에 소스코드가 나오게 되면 역공학(Reverse Engineering)을 통해 UML 모델을 만들어내자는 제안을 하기도 했다. 모델과 코드간의 동기화를 위해 역공학을 이용하지만 과연 이것이 시간을 줄이는 방법일까?
개발 프로세스와 과도한 모델링
무엇을 모델링 할 것인가? 어느 정도의 정밀도 수준으로 모델링 할 것인가? 모델링의 범위는 어떻게 설정해야 하는가? 이러한 질문에 답하기 위해 이것저것 고민해보기도 하고 업계에 종사하는 분들과 메신저로 혹은 술자리에서 때로는 프로젝트 회의 시간에 토의를 많이 해 보았다. 그 중 필자가 알고 지내는 대부분의 개발자들의 한결같은 주장은 '과도한 모델링'의 압박에 시달린다는 것이었다. 이야기를 해 본 결과 실제로 개발자들이 느끼는 '과도한 모델링'의 기준은 주관적이었지만 몇몇 주장은 일견 수긍이 가기도 했다.
그 중에 하나가 프로세스의 적용 문제였는데 지구상에 존재하는 모든 프로젝트는 서로 다른 시스템을 만들고 있기 때문에 모든 프로젝트 천편일률적으로 적용되는 모델링 범위나 정밀도 수준은 없다. 하지만 그것을 프로젝트의 규모나 도메인의 종류 등의 일반화된 기준으로 묶고 그 기준에 해당하는 개발 프로세스를 제공해야 한다. 예를 들어 현재 우리나라에서는 RUP(Rational Unified Process)나 마르미와 같은 프로세스 프레임워크를 많이 사용한다. 또 SI 업체에서는 자체적으로 발전시켜온 방법론이나 앞에서 언급한 RUP 또는 마르미를 기반으로 하여 자체 프로세스를 개발하여 사용한다.
문제는 각 프로젝트마다 프로세스를 조정(Tailoring)해서 적용해야 하는데 현실은 그렇지 않다는 것이다. 심지어 이런 이야기를 들은 적도 있다. "CBD를 적용하기엔 우리 프로젝트 규모에 좀 안 어울리지 않나요? 아는 사람한테 물어봤더니 규모가 작으면 CBD가 안 어울린다고 하더라고요. 대신 굳이 CBD를 하려면 UML 모델링 툴을 반드시 도입해서 진행해야 한다고 하던데…" 누가 이 분에게 그런 이야기를 했는지 모르지만 이 정도 되면 거의 사기에 가깝다. 그 분이 생각한 CBD라는 것이 무엇이었는지 어림짐작되는 대목인데 마치 신발에 발을 맞추는 꼴이 되어 버렸다.
발을 보호하는 것이 1차적인 목표이고 멋도 부리는 것이 신발을 신는 2차 목표라고 보면, 우선 성공적인 프로젝트를 수행하기 위해 프로세스를 도입하고 이왕 개발할 것 좀 체계적으로 가이드를 받아보자는 목적도 있을 것이다. 객체지향이나 CBD와 같은 단어의 의미는 일단 논외로 하고 앞에서 언급한 프로세스 조정에 관하여 이야기 해보자.
프로세스 조정
앞에서 언급했듯이 RUP나 마르미는 일반적이고 범용적인 개발 프로세스이다. 세 달간 3명이 개발하는 프로젝트와 2년간 50명이 개발하는 프로젝트 모두 개발 프로세스가 같을 수 있겠는가? MS 워드와 같은 워드프로세서를 개발하는 것과 은행을 위한 전산 시스템을 개발하는 개발 프로세스가 같을 수 있겠는가?
서로 다른 특성을 갖는 프로젝트를 위해 프로세스 조정(Tailoring)이란 작업을 하게 되는데 여기서 유의해야 할 것은 조정할 수 있는 영역을 제한해야 한다는 것이다. 프로젝트 현장에서 편의대로 프로세스를 고치거나 누락시켜서는 안되고 프로세스 조정의 결과는 승인되어야 한다. 더 나아가 프로젝트 세부 유형에 따른 개발 프로세스를 제공한다면 더할 나위 없이 좋을 것이다. 프로세스의 대표적인 구성 요소로는 작업 영역, 작업 흐름, 활동, 산출물, 역할 등이 있다. 필자는 이 모든 것이 프로세스 조정 대상이 될 수 있다고 생각한다.
RUP의 경우 '프로세스 엔지니어'가 프로세스 조정 작업을 진행하고 마르미 경우 ‘도구 및 방법론 관리자’가 그 역할을 수행한다(XP의 경우는 코치라고 한다. 편의상 이 글에서는 모두를 프로세스 엔지니어라고 칭하겠다). 이런 역할의 특성상 다른 사람과의 의견 교환이나 대립이 있기 때문에 프로세스 엔지니어는 소프트웨어 개발에 관한 폭넓은 지식을 갖고 있어야 하며 의사소통 능력이 있어야 한다. 프로젝트 관리자나 프로젝트 리더 또는 시스템 분석가나 아키텍트를 설득해야 할 일이 있을 수도 있다.
프로젝트 관리자나 프로젝트 리더는 프로젝트 관리 관점으로 개발 프로세스를 바라볼 것이고 시스템 분석가나 아키텍트는 소프트웨어 시스템을 개발하는데 중요한 결정을 내리기 위한 관점으로 프로세스를 바라보며 자신의 의견을 제시 할 것이다. 이들의 의견을 통합하고 조정하며 고객의 요구를 반영하여 해당 프로젝트의 상황에 맞는 프로세스로 조정하게 된다.
![]() |
<그림 2> 프로세스 엔지니어의 활동과 산출물 |
<그림 2>에서 프로세스 엔지니어는 현 개발 조직 평가, 개발 케이스(Development Case) 작성, 프로젝트 전용 템플릿 작성의 세 가지 활동을 하게 된다. 이에 따른 개발 조직 평가, 개발 케이스 프로젝트 전용 템플릿의 세 가지 산출물을 작성하는데 여기서 가장 핵심적인 산출물은 개발 케이스이다. 특정 프로젝트를 위한 프로세스를 조정하고 개발 케이스를 작성하기 위해서는 프로젝트의 상황을 이해 할 필요가 있는데 이를 위하여 현 개발 조직에 대한 평가가 이루어져야 한다. 또한 개발 조직 이외에도 고객에 대한 평가도 동시에 이루어져야 한다.
예를 들어, 기업을 위한 애플리케이션을 개발한다고 가정한다면 개발 완료 후에 고객은 유지보수를 위한 산출물을 요구할 것이다. 프로세스 엔지니어는 개발 조직 및 고객을 대상으로(좀 더 의미를 확장하자면 이해관계자를 의미 할 수 있다) 현 개발 조직에 대한 평가를 할 때 프로세스, 툴, 사람들의 능력, 사람들의 태도, 고객들, 사용 기술, 문제점, 개선 분야의 관점에서 개발 조직의 현재 상태를 평가한다.
프로세스 조정을 위한 요구사항을 파악하고 이를 근거로 프로세스 조정을 실시한다. 프로세스 조정의 결과는 개발 케이스이다. 프로세스 조정에 관한 자세한 사항을 알고 싶으면 RUP나 마르미 또는 Barry Boehm과 Richard Turner가 쓴 『Rebalancing Your Organization's Agility and Discipline』를 참조하면 도움이 될 것이다.
케이스 툴을 쓰면 생산성이 높아지는가?
Steve McConnell은 그의 저서인 『Professional Software Development(2003)』에서 코끼리에 관한 재미있는 이야기를 소개했다. 이야기를 요약하면 이렇다.
고대 이집트 어느 왕의 피라미드를 만드는 공사가 한 참 진행 중이었다. 엄청나게 큰 암석을 사람들이 일일이 날라야 했으므로 공사의 진척은 매우 더디었다. 그래서 공사 프로젝트 관리자는 고민 끝에 어디선가 코끼리라는 엄청난 동물이 있는데 이 동물은 사람이 운반하는 것 보다는 몇 배 혹은 몇십 배 높은 생산성은 낸다는 이야기가 얼핏 기억이 기억났다. 이 동물만 들여오면 지금까지 지연되었던 일정을 단번에 만회할 수 있을 것 같은 생각이 들었다.
공사 프로젝트 관리자는 그 동물을 도입하기로 결심하고 일을 추진했다. 코끼리라는 동물을 들여놓고 보니 과연 듣던 대로 몸집도 엄청나고 그에 걸맞게 힘도 대단했다. 공사 프로젝트 담당자는 입가에 미소를 머금으며 공사현장에 코끼리를 투입하라는 지시를 내렸다. 그러나 그 동물을 투입하는 순간 순조롭게 진행될 것 같은 공사가 점점 이상하게 진행되고 일정도 생각했던 것만큼 줄여지지 않았다. 줄여지기는커녕 오히려 사람이 진행했던 것보다 더 늦어지는 조짐이 보였다.
공사 프로젝트 관리자는 상황파악에 나섰는데 공사 현장에 가서 자세히 관찰을 해보니 문제를 바로 파악할 수 있었다. 바로 코끼리를 다룰 수 있는 사람이 없었던 것이었다. 그의 공사팀은 그런 동물을 부리면서 일을 한 적이 단 한번도 없었기 때문에 기존의 공사프로세스와 엄청난 혼선을 빗었다. 또 코끼리에 대해 아는 것이 전혀 없었기 때문에 코끼리를 돌보지 못해 걸핏하면 앓아눕기 일 수였고 몇몇 코끼리는 도망가 버려 엄청난 비용을 들여 도입한 코끼리가 무용지물이 되어 버렸다. 공사 진행은 그 만큼 지연되었고 코끼리를 포기할 수밖에 없었다"
필자가 보기엔 그 코끼리가 바로 케이스 툴이 아닌가 싶다. 프로젝트 생산성을 높이기 위해 케이스 툴을 도입하는 것은 바람직하지만 그 생산성을 높이기 위해서는 일정 기간의 훈련이 필요하다. 요즘 나오는 케이스 툴은 기능도 막강하고 더불어 복잡하다. 또 종류도 많아 수많은 케이스 툴과 연동도 필요하다. 일례로 IBM 래쇼날의 스위트 제품은 내장하고 있는 서브 제품만 해도 10여 가지가 넘는다. 다른 케이스 도구도 사정은 다를 바 없다.
프로젝트 현장의 요구는 이러한 제품을 좀 편하게 사용하고 싶어 한다. 소프트웨어 개발 라이프 사이클 전반에 걸쳐 케이스 툴을 적용하려고 서로 다른 회사 목적이 다른 툴을 서로 연계시켜야 한다. 이 일은 대단히 복잡하고 가변적이어서 앞의 요구를 충족시키려면 프로세스적으로나 케이스 툴에 대한 상당한 지식과 수준의 기술이 요구된다.
요구사항관리 도구와 분석/설계를 위한 모델링 도구와의 연계 부분, 모델링 도구와 개발 및 테스팅 도구와의 연계 부분이 대표적인 연계 부분이다. 또한 각 케이스 툴에서 쏟아져 나오는 다양한 모델과 문서들을 통합적으로 관리할 수 있는 형상 및 변경 관리와 각 작업영역(요구사항, 분석/설계, 구현, 테스트 등)을 기반으로 하여 반복 개념으로 프로젝트를 관리해야 하므로 실제 케이스 툴이 소프트웨어 개발을 도와주려면 아주 많은 것들을 고민해야 한다.
특히 프로젝트 현장에서 따르고 있는 프로세스를 정확히 지원해줘야 하므로 케이스 툴 자체의 유연성도 갖춰야 한다. 케이스 툴은 단어의 의미에서와 같이 소프트웨어 개발을 정말로 도와주는 케이스 툴이 되어야 하지 않을까 싶다.
머릿속 아이디어를 모델로 구체화하기
필자는 항상 프로젝트를 진행하다 보면 항상 딜레마에 빠지는 문제가 있다. 프로젝트에 참여하는 사람들이 UML을 잘 모르는 경우이다. UML을 모델링 언어로 채택한 프로젝트는 그 프로젝트에 참여하는 모든 사람들이 UML을 알고 있어야 한다는 전제조건이 따른다.
하지만 현실은 어떠한가? 프로젝트를 수주해야만 먹고 사는 개발 업체의 경우 UML을 알던 모르던 일단 수주를 해야만 하는 상황이다. 그 회사의 개발팀 구성원이 UML을 잘 알고 있다면 문제가 없겠지만 잘 모르는 경우 심하면 그 구성원 중 단 한 명도 제대로 알지 못하는 경우 문제가 아닐 수 없다.
이 때 가장 많이 활용하는 방법은 UML을 알고 있는 사람이나 업체를 고용하여 먼저 샘플을 만들게 한 후 그것을 템플릿으로 하여 모델링을 진행하는 것이다. 물론 이런 프로젝트가 많아야 필자 같은 사람들이 먹고 살긴 하겠지만 프로젝트 입장에서는 참 못마땅한 일이 아닐 수 없다.
예를 들어 UML을 알고 있는 사람이 시스템의 한 부분에 대하여 클래스 다이어그램을 그렸다고 하자. 그 클래스 다이어그램이 샘플로 나오면 다른 모든 사람들은 그 샘플을 기반으로 모델링을 시작하게 된다. 맞는지 틀리는지 자신의 판단 기준이 없는 채로 샘플을 '다른 이름으로 저장하기'로 해서 따로 하나는 만들어 놓은 다음 다이어그램을 그리고 저장을 한다. 예전에 학교에서 다른 친구 소스코드 구해다가 변수명 좀 바꾸고 약간 짜깁기해서 리포트를 제출하는 것과 비슷한 상황이 된다.
다이어그램이야 만들어 졌지만 모델링을 하는 사람이 그 모델이 적합한지 아닌지 판단할 수 없으므로 그려진 다이어그램을 들고 샘플을 만든 사람에게 달려와 이것저것 물어본다. 물론 어쩔 수 없는 상황이고 그런 과정을 거치면서 사람들의 모델링 실력이 향상되겠지만 모르면서 그림을 그리는 사람도 답답하고 프로젝트 진행에도 문제가 많다.
잘 모르는 사람이 프로젝트를 하는, 어떻게 보면 시작부터 이상하긴 하지만 어쩔 수 없다고 보고 조금이나 도움이 되도록 머릿속의 아이디어를 모델로 구체화 하는 과정을 소개하면 조금 낫지 않을까 싶다.
시작은 글쓰기부터
만들고자하는 모델이나 그리고자 하는 다이어그램에 따라 접근 방식이 다르겠지만 결국 시작은 머릿속의 생각을 글로 정리하는 것부터 시작한다. 글로 쓰기 귀찮다면 메모장이나 화이트보드에 본인의 생각을 간단하게나마 자유로운 형식으로 정리하면서 시작하게 된다.
예를 들어, 고과장이 애플리케이션 프레임워크를 모델링 한다고 가정해 보자. 프레임워크를 모델링하는 사람이 UML을 설마 모르진 않겠지만 이 사람이 어떤 과정을 거치면서 머릿속 아이디어에서부터 구체적인 모델을 만들어 가는지 살펴보자. 고과장은 프레임워크의 한 부분을 모델링하기 위해 고심하다가 머릿속에서만 맴도는 아이디어를 글로 써보기로 했다.
클라이언트에서 어떠한 메시지를 보내면 프레임워크에서는 그 메시지를 해석하여 어떤 비즈니스 로직을 수행할 지 결정하여 수행한다. 메시지에 따라 수행하는 비즈니스 로직은 메시지가 변해도 동일한 비즈니스 로직이 수행되어야 하거나 동일한 메시지에도 상황에 따라 비즈니스로 로직이 바뀔 수 있어야 한다.
써 놓고 읽어보니 대충 어떤 방향으로 만들어야 할지 느낌이 좀 오기 시작했다. 왠지 잘 될 것 같은 느낌으로 입가엔 미소를 머금으며 모델링 도구를 실행시켰다.
모델링을 시작하다
우선 고과장은 클라이언트와 클라이언트가 보내는 메시지를 받는 무엇인가가 있어야 하지 않을까 하는 생각이 들었다. 또 어떤 비즈니스 로직을 수행할지 판단하는 객체도 있어야 할 것 같고, 클라이언트가 보낸 메시지에 대응하는 비즈니스 로직을 갖고 있는 정보를 갖고 있는 객체도 있어야 할 것 같다.
고과장은 우선 '클라이언트', '메시지 판단자', '메시지와 비즈니스 로직 맵핑 정보' 등이 객체가 되지 않을까 생각했다. 모델링 툴을 띄워놓고 세 가지 객체를 그리고 나니 이들 간의 관계와 각 객체가 어떤 일을 해야 하는지(Responsibility)가 알쏭달쏭 했다. 그래서 이 세 가지 객체를 놓고 이들 객체가 서로 어떻게 인터랙션(Interaction)하는지 알아보기 위해 시퀀스 다이어그램을 그려보기로 했다.
![]() |
<그림 3> 개념 정리를 위한 시퀀스 다이어그램 |
이렇게 그려놓고 보니 객체 간에 어떻게 교류하는지 눈에 들어와 더 구체적으로 생각할 수 있게 되었다. 고과장은 시퀀스 다이어그램을 보면서 차근차근 짚어보기로 했다. 클라이언트가 메시지를 '메시지 판단자'에게 보내면 해당 메시지에 대응하는 비즈니스 로직을 알려주고 메시지 판단자가 비즈니스 로직을 수행하여 클라이언트에게 보내주는 깔끔한 형태로 정리된 것 같았다.
뭔가 빠진 것 같은데?
하지만 객체 간에 어떻게 교류하는지 눈에는 보였지만 왠지 무엇인가 빠진 듯한 느낌이 들었다. 시퀀스 다이어그램을 쳐다보고 있으니 메시지 판단자가 '비즈니스 로직 수행'을 하는 것이 메시지 판단자의 역할에 비해 좀 오버하는 듯한 느낌이 들었다. 또 비즈니스 로직 수행이 잘 되었는지 아닌지 판단하는 부분도 있어야 할 듯 했다. 그래서 '비즈니스 로직 수행자'라는 이름은 좀 이상하지만 이런 객체를 따로 빼 두어 시퀀스 다이어그램을 보완하기로 했다.
![]() |
<그림 1> 산출물의 종류와 UML간의 관계 |
비즈니스 로직 수행자를 넣어 시퀀스 다이어그램을 다시 그려보니 이제 뭔가 맞아 돌아가는 느낌이 들었다.
![]() |
<그림 5>"그림 3"의 클래스 다이어그램 |
UML의 시퀀스 다이어그램과 클래스 다이어그램을 통해 객체간에 교류와 각 객체의 책임(Responsibility)를 찾아냈다.
설계를 위한 모델로 발전
이제 개념적으로 정리한 모델을 바탕으로 좀 더 구현하기 좋은 형태로 발전시켜 보자. 구현을 위해서는 좀 구체적인 형태로 정의하고 실제적인 비즈니스 로직 처리와 에러 처리를 표현하기 위한 무엇인가가 필요했다. 고과장은 고민 끝에 웹 서버로부터 아이디어를 얻었다. 웹 서버는 웹 브라우저와 커뮤니케이션을 위해 Request와 Response를 사용한다. 브라우저의 요청은 Request에 담아 웹 서버로 보내고 웹 서버의 응답은 Response에 담아 브라우저로 보내게 된다. 이런 비슷한 개념을 프레임워크에 적용해보면 어떨까 생각했다.
즉, 클라이언트의 요청은 BusinessRequest에 담아 보내고 서버의 응답은 BusinessResponse에 담아 보내되, 비즈니스 로직 수행시 Exception이 발생하면 BusinessResponse에 담아 메시지 판단자가 처리하게 하면 어떨까 하는 생각을 했다. 고과장은 이렇게까지 생각이 정리되자 시퀀스 다이어그램을 통해 아이디어를 구체화 해보기로 했다. 시퀀스 다이어그램은 <그림 6>과 같다.
![]() |
<그림 6> 보다 더 구체화된 시퀀스 다이어그램 |
클라이언트 쪽의 예상 소스코드도 넣어 보고 메시지를 비즈니스ID라는 용어로 바꿔봤다. 또한 비즈니스ID의 해당 비즈니스 로직을 실행시키기 위해서는 리플렉션(Reflection)이라는 기술도 써야 할 것 같고 Exception 처리를 위한 부분도 따로 둬야겠다는 생각이 들어 BusinessResponse에 BusinessExcuteHelper가 Exception을 담아주는 형태로 모델링을 했다.
<그림 6>의 시퀀스 다이어그램을 보면 중간 중간 노트가 많이 달려있는 것을 볼 수 있다. 시퀀스 다이어그램의 중간 중간을 보면 샘플 코드나 리플랙션, Exception과 같은 구현을 염두 한 노트를 볼 수 있다. UML로 모델링을 할 때 노트의 역할은 필수 불가결한데 해당 다이어그램의 이해를 돕기 위해서나 모델러의 의도를 명확히 하기 위해서 또는 아직 불분명한 부분이 있을 경우 판단에 도움이 될 만한 주석을 달기 위한 수단으로 이용하면 좋다.
구체화된 모델
자 이제 구현을 위한 시퀀스 다이어그램도 그렸고 구체적으로 어떻게 접근하면 될지 방안이 섰기 때문에 최종 클래스 다이어그램을 그려보기로 했다. 클래스 다이어그램을 그리면서 고과장은 클라이언트가 보내는 메시지와 해당 비즈니스 로직 정보를 어떤 형태로 할 까 고민하다 XML 형태로 하는 것이 가장 좋을 것 같다는 판단이 들었다.
애플리케이션이 실행되면서 XML에 있는 정보를 읽어 캐싱하고 있는 형태로 만들고 그 역할은 BusinessMapper라는 객체에 해당 정보를 Map에 담아 두기로 했다. BusinessMapper는 단 하나만 존재해야 하므로 싱글턴(Singleton) 패턴을 적용하기로 했다(실제 구현을 하기 위해서는 보다 더 구체적으로 모델링을 해야겠지만). <그림 7>는 고과장의 아이디어를 반영한 최종 클래스 다이어그램이다.
![]() |
<그림 7> 고과장 생각을 정리한 최종 클래스 다이어그램 |
이 클래스 다이어그램에서 XXX_ServerPage나 XXX_Action, XXX_ActionForm, XXX_Mgr과 같이 XXX라는 접두어가 붙은 클래스는 비즈니스 로직 개발자들이 직접 만들어야 하는 부분이다. 개발자들은 XXX라는 접두어가 붙은 클래스만 개발하면 되고 고과장이 만든 프레임워크에 끼워 넣어 어떤 메시지가 어떤 비즈니스 로직과 맵핑되는지 XML 파일만 편집하면 되는 구조로 모델링이 되었고 고과장의 생각대로 메시지와 비즈니스 로직과의 느슨한 관계를 유지할 수 있는 모델이 만들어 졌다.
일단 이런 구조의 프레임워크가 좋은 것인지 아닌지는 일단 논외로 하고 머릿속의 아이디어를 모델로 구체화하는 과정을 다시 한번 정리하자면 우선 1) 머릿속의 아이디어를 글로 정리하고 2) 정리한 글을 바탕으로 UML로 바꿔 본다. 이때 동적인 측면과 정적인 측면을 고려하고 전에 정리한 글에서 UML로 변환하는 과정에서 빠진 것은 없는지 미처 생각하지 못한 것들이 있는지 확인한다. 그냥 글로 확인하는 것보다는 UML의 시퀀스 다이어그램이나 엑티비티 다이어그램 등을 이용하여 확인하면 보다 더 정확하게 모델링할 수 있다. 3) 이렇게까지 진행이 되었으면 실제 구현을 위한 모델로 발전시켜 본다. 특정 플랫폼이나 개발언어, 미들웨어 등을 고려하면서 그려나간다.
결국 1)~3)까지가 실제 모델링을 통해 아이디어를 구체화 시켜나가는 모든 것이다. 1)번을 잘 하기 위해 각종 기법(예를 들어, 유스케이스나 유저스토리 등)이 동원되고 2)번을 잘 하기 위해 CRC 카드와 같은 기법이 사용된다. 3)번 역시 마찬가지로 각종 설계 패턴이나 J2EE 패턴과 같은 것을 참조한다. 개발 프로세스에 따라 어떤 모델을 만드는가, 어떤 산출물을 만드는가에 따라 그려야 할 다이어그램이나 모델의 정밀도가 다르겠지만 결국 1)~3)까지의 행위를 반복함으로써 우리가 얻고자 하는 모델을 얻어낼 수 있다.
쉽고도 어려운 유스케이스 모델링
1960년대 후반쯤 이바 야콥슨에 의해 만들어진 유스케이스는 1990년대에 들어서면서 아주 폭넓게 사용하는 요구사항 파악 및 분석 기법으로 자리 잡았다. 우리나라의 경우 아마도 대부분의 프로젝트에서는 유스케이스라는 이름의 산출물을 만들고 있고 만들었을 것이다. 필자도 여러 프로젝트를 하면서 유스케이스를 써서 요구사항 분석을 했었다.
초기 접근하기에 개념적으로 어려운 부분이 별로 없기 때문에 누구나 의욕적으로 참여하여 유스케이스를 작성해 해 나간다. 하지만 이 유스케이스라는 것이 단순해 보이지만 결코 만만치 않은 특성을 갖고 있다. 처음에는 쉬운 듯하지만 진행해 나갈수록 어려워지는 경향이 있다. 또한 프로젝트의 진행 상태나 규모에 따라 유스케이스 작성 방식이 달라진다. 이러한 특성 때문에 바쁜 프로젝트에서 뭔가 별 고민을 하지 않고 쉬운 작성 형식이나 방법을 목말라하는 개발자들에게는 혼돈의 연속일 수밖에 없다.
필자 개인적으로 유스케이스에 관해 잘 설명한 도서는 Alistair Cockburn의 『Writing Effective Use Cases (2001)』이다. 영어에 어려움을 겪는 분들은 번역본도 나와 있으니 구해서 한번 꼭 읽어보길 바란다. 이 책의 내용 중에 유스케이스 작성시 주의할 점이 있는데 그 중 현장에서 실제로 많이 나타나는 몇 가지를 소개하고자 한다. 일부 주의사항은 책에서 발췌하고 필자가 느낀 점을 중심으로 설명해본다.
유스케이스는 산문체 수필이다
유스케이스 다이어그램을 갖고 지지고 볶던 독자들에게는 약간 의아한 말일 수 있다. 사실 유스케이스는 텍스트 기반의 서술이다. UML의 유스케이스 정의를 보아도 '유스케이스는 시스템 전체나 유스케이스 일부 행동을 명세화 하고 순차적으로 발생하는 활동들을 서술하는 것이다. 시스템은 이러한 활동을 수행하여 액터에게 원하는 결과를 준다'라고 되어 있다. 그래픽으로는 타원으로 표현하고 중심에는 몇 단어로 이루어진 이름이 있다.
프로젝트를 진행하면서 다이어그램에 얽매여 오로지 다이어그램만으로 유스케이스를 작성하려고 하면 관련 팀은 점점 어려움으로 빠져 들게 된다. 유스케이스 다이어그램 그 자체가 담고 있는 정보는 매우 한정적이다. 유스케이스명과 어떤 액터와 관계가 있는지를 나타내는 선 몇 개, 복잡하게 뒤 얽힌 '포함(include)와 확장(extends)을 표현하는 점선들이 뒤덮여 있을 뿐이다. 사람들이 그 다이어그램을 보고 요구사항이 뭔지 정확하게 알 수 있을까?
단어 몇 개로 이루어진 유스케이스 명을 보고 무엇을 하는 유스케이스인지 추측을 할 뿐이다. 다이어그램의 정보가 충분치 않으므로 답답한 마음에 다이어그램에 갖가지 정보를 넣으려고 하고 유스케이스의 목표 수준은 점점 내려가고 복잡해지는 현상이 나타난다. 결국 아무도 이해할 수 없는 다이어그램이 만들어지면서 오히려 팀간의 명확한 이해의 공유는커녕 혼란만 가중시키는 결과를 낸다. 유스케이스 다이어그램만을 놓고 이틀 동안 논쟁만 하는 개발팀을 실제로 보았다. 다시 한번 강조하지만 유스케이스는 텍스트 형식의 서술이다. 액터와 유스케이스 간에 어떤 일이 일어나는지 글로 적음으로써 이해를 명확히 할 수 있다.
유스케이스와 사용자 매뉴얼
유스케이스 교육을 들어 봤거나 프로젝트를 해 본 분들이면 아마도 귀가 따갑게 유스케이스는 GUI에 관한 부분은 적지 않는 것이라고 들어왔을 것이다. 유스케이스를 작성하면서 유저 인터페이스에 관한 내용을 언급하기 시작하면 유스케이스가 점점 사용자 매뉴얼이나 화면 설계서처럼 변해간다.
유스케이스는 향후 작성할 분석/설계 모델이나 화면 설계 등의 모델의 기본 정보를 제공한다. 또한 유스케이스로 추적(Trace)할 수 있다. 아니 추적되어야 한다. 사용자 매뉴얼이나 화면 설계서가 분석/설계 모델의 상위 요건이 될 수 있는가? 결코 그렇지 않다. 유스케이스는 적당한 목표수준으로 작성함으로써 상위 요건으로써의 역할을 다 할 수 있어야 한다.
포함과 확장의 오남용
어떤 유스케이스 다이어그램을 보면 다이어그램 가득히 실선과 점선이 어지럽게 꼬여 있는 그림을 가끔 본다. 왜 이런 다이어그램이 나오는지는 앞에서 언급하였다. 필자의 경우 이런 다이어그램은 십중팔구 뭔가 잘못되었을 것이라는 예감이 뇌리를 스친다. 우선 복잡하면 제대로 파악할 수 없고 서로 이해를 명확하게 하지 못했을 가능성이 높으며 이해도가 떨어지는 상황에서 유스케이스가 제대로 작성되었을 리가 없다.
유스케이스 다이어그램이 복잡하면 각 유스케이스의 이벤트 흐름을 작성하면서 아주 여러 부분에 포함(include)과 확장(Extends)이 나타나게 되고 결국 전체적으로 유스케이스의 유지보수를 어렵게 만든다. 유지보수가 어렵게 되면 요구사항을 정확히 담는데 점점 힘들어지고 현실과 동떨어진 그저 서로 다른 이해수준으로 각자의 머릿속에만 존재하는 요구사항이 나오게 된다.
최초 확장이라는 개념이 등장하게 된 이유는 이전 시스템의 요구사항 파일을 건드릴 수 없다는 실행 지침 때문이었다(Alistair Cockburn, 2001). 그 당시 개발팀의 임무는 새로운 서비스를 추가하는 것이었고 기존의 요구사항 문서를 건드릴 수 없는 상황에서 원래의 요구사항은 한 줄도 건드리지 않은 채 새로운 요구사항을 추가했다. Alistair Cockburn은 확장이 필요할 경우 다이어그램 상에서 보여주지 말고 기존 유스케이스 안에서 확장 유스케이스의 참조를 그저 텍스트로 서술할 것을 권유한다. 다이어그램에 복잡하게 확장을 표현함으로써 정작 중요한 유스케이스를 볼 수 없게 만들기 때문이다. 필자도 그의 주장에 동의 한다.
케이스 툴로 유스케이스 작성하기
케이스 툴로 유스케이스를 작성한다는 것이 잘못되었다는 것은 아니다. 오히려 케이스 툴이 활용상의 문제로 인해 정확한 유스케이스를 작성하는데 걸림돌로 작용하는 현상을 이야기하고 싶은 것이다. 필자는 지금까지 프로젝트를 진행하면서 유스케이스의 고단함에 대해 무척 많은 고민을 했었다. 일반적으로 개발자들은 작문을 싫어하는 습성이 있지만 요구사항을 파악하고 분석하는 사람들은 일반 고객과의 의사소통이 많기 때문에 산문 형식의 문서 작성(Technical Writing)에 능숙해야 함에도 불구하고 대부분의 프로젝트에서는 이러한 사실을 애써 외면한다.
작성하기 귀찮은 유스케이스를 케이스 툴로 그리고 끝내 버리려는 생각을 한다. 사실 필자도 예외는 아니어서 웬만하면 케이스 툴에서 모든 걸 해결하고 싶은 유혹에 항상 시달렸다. 하지만 대부분의 케이스 툴은 유스케이스를 서술하기 위한 조그만 다이얼로그 창만을 제공한다. 유스케이스를 기술한 문서를 따로 하이퍼링크 방식으로 케이스 툴과 연결하는 방법을 주로 취했는데 사실 힘들고 불편하다. 만약 어떤 케이스 툴의 기능 중에 일정한 유스케이스 작성 형식의 레이아웃을 디자인할 수 있고 그 템플릿 안에서 유스케이스를 작성하면 다이어그램이 역으로 만들어지는 케이스 툴이 있다면 얼마나 좋을까 하는 생각을 해본다. 언제쯤이면 편하게 유스케이스 모델링을 할 수 있는 케이스 툴이 나올까?
분석/설계 모델과 MDA
분석(分析)은 그 단어의 의미에서도 알 수 있듯이 무엇인가를 어떠한 목적 때문에 나누어(分) 쪼개는(析)것이다. 소프트웨어 개발에서 나누어 쪼개야 할 필요가 있는 부분은 문제 영역으로 시스템을 개발하는 사람들이 문제 영역을 올바로 이해하기 위한 목적으로 분석을 한다. 이해한 것을 즉시 시스템으로 만들 수 없으므로 중간에 문제 영역의 이해와 실 시스템간의 가교역할을 하는 것이 있는데 그것이 바로 설계이다.
사실 웬만하면 설계를 하지 않고 시스템을 만들고 싶은데 구현 언어나 플랫폼 등의 영향을 많이 받기 때문에 분석한 결과를 바로 시스템화하기 힘든 것이다. 현재 분석에서 설계를 거치지 않고 바로 실 시스템으로 건너가기 위한 노력이 진행되고 있는데 독자 여러분들도 잘 알다시피 MDA(Model Driven Architecture)가 그것이다.
현재 소프트웨어를 만드는 사람들의 작업 행태는 당연하게 생각되지만 지루하게도 4단계를 거친다. 문제 영역을 파악하고 분석하여 그 결과를 바탕으로 설계한 후 소프트웨어를 구현한다. 만약 정말 MDA가 활성화 된다면 중간에 1가지 단계가 빠지는 3단계 개발 공정이 나올 것이며 그저 요구사항 파악해서 분석 모델을 만들어 놓으면 실행 시스템이 튀어나오는 정말 환상적인 세상이 오지 않을까 싶다. 그런데 정말 이런 세상이 가능할까?
현 컴퓨팅 시스템은 다 계층 분산 시스템인 관계로 많은 설계 요소와 다양한 관련 기술이 필요하다. 이 모든 기술을 모두 알 수 없으므로 특정 기술 기반을 가진 사람들이 한 프로젝트에 모여 개발을 하고 그 중 충분한 경험과 깊은 지식을 갖고 있는 누군가가 아키텍트라는 역할로 소프트웨어 개발을 이끌고 나간다.
아키텍트라는 일반 비즈니스 로직 개발자들의 개발 자유도를 통제하기 위해 '메커니즘'이 라는 것도 만들어 놓고, 마음이 안 놓이는지 '프레임워크'라는 것도 만들어 놓아 오직 비즈니스 로직 구현에 몰두할 수 있게 만들어 놓는다. 비즈니스 로직 개발하는 것도 '패턴'이라는 이름으로 개발하는 방식을 제한하는 경우가 많다. MDA에서는 이러한 부분을 프로파일로 작성한다. 이 프로파일을 바탕으로 비즈니스 분석 모델을 빌드하면 실행 컴포넌트가 나오게 된다.
현재도 제품으로 출시되어 있는 MDA 솔루션들이 있다. 필자가 보기엔 어떤 솔루션은 무늬만 MDA인 것도 있고 실제 MDA의 비전에 상당히 근접한 솔루션도 있었는데 모델링 도구에서 모델을 만들고 OCL을 작성해 놓으면 놀랍게도 실제로 시스템이 작동했었다. 다만 일부 표준을 지원하지 않아 문제가 되긴 했지만 말이다.
하지만 언젠가는 MDA가 우리 피부에 와 닿을 정도로 현실화 되리라 믿는다. 초창기 컴퓨팅 환경에서 고급 언어로 일컫는 3세대 언어들은 그 당시 개발자들에겐 환상적인 꿈의 개념이었다고 한다. 기계어와 어셈블리 수준에서 프로그래밍을 하던 그들에게는 자연어와 비슷한 모양의 개발 언어는 얼마나 환상적으로 보였을까? 지금 우리는 이와 같은 과도기를 겪고 있다고 필자는 생각한다. 독자 여러분들도 그런 시대를 대비하여 하루빨리 모델링 능력을 한껏 끌어올리기 바란다.
자바 웹 애플리케이션 모델링
만약 개발 프로세스가 비슷하다면 그 프로세스를 적용하여 개발하는 모든 애플리케이션 모델링의 방법은 거의 유사하다. 웹 애플리케이션이라고 해서 별다르게 특이한 것은 없겠지만 웹 애플리케이션의 특성상 몇 가지 짚고 넘어갈 부분이 있다. 사실 엄밀하게 말 하면 웹이라는 특성도 있지만 자바의 특성으로 인해 모델링 방법이 약간 달라지는 수준으로 볼 수 있다. 특히 현 엔터프라이즈 컴퓨팅 환경은 다 계층 분산 시스템이므로 계층과 분산에 관한 부분의 모델링이 강조된다.
또한 사용자 웹 인터페이스 모델링도 중요한 부분으로 생각할 수 있다. 웹 페이지의 특성상 HTML이라는 제약으로 인해 약간 특이한 점이 있다. 웹 페이지 모델링에서 폼(form)과 같은 구성요소는 스테레오 타입(stereo type)으로 정의하여 모델링을 한다. 또 웹 페이지는 화면의 흐름에서 해당 정보를 갖고 다니거나 세션을 참조하기 때문에 어디까지 해당 정보를 갖고 다닐지 세션을 어떻게 참조할 지가 모델링의 주요 포커스가 된다. 일단 개요 수준은 여기까지 하고 실제 예제를 보면서 모델링이 어떻게 진행되는지 살펴보자.
분석 모델
좀 전에도 언급했듯이 웹 애플리케이션도 역시 다른 시스템과 마찬가지로 요구사항 파악 및 분석으로부터 시작한다. 요구사항을 위한 모델링으로 유스케이스를 이용하는 것은 이미 앞에서 이야기했고 특집 4부에서 자세히 다룰 예정이므로 유스케이스 자체에 관한 설명은 하지 않겠다. 또한 웹 애플리케이션이나 다른 기술을 이용한 애플리케이션이나 요구사항과 분석 모델링의 기법은 사실 별반 다르지 않다. 분석 모델은 구현과 관계가 없는데 분산(distribution), 영속성(persistency), 커뮤니케이션(communication), 인증(authentication)과 같은 메커니즘과 상관없는 개념적인 모델이기 때문이다. 즉, 유스케이스 모델을 기반으로 분석관점으로 유스케이스 실현(realization)을 표현한 객체모델이 바로 분석 모델이다.
![]() |
<그림 8> 분석 클래스 다이어그램의 예 |
<그림 8>은 분석 모델의 유스케이스 실현(realization)에 참여하는 분석클래스 다이어그램이다. RUP에 의하면 분석클래스는 <<boundary>>, <<control>>, <<entity>> 등 세 가지 종류의 스테레오 타입을 갖는다. 원래 스테레오 타입은 태기드 벨류(tagged value)와 함께 UML의 확장 메커니즘의 한 종류이기 때문에 필요하다면 추가적인 스테레오타입을 정하여 사용하여도 무방하다.
사용자 웹 인터페이스 모델링
사용자 웹 인터페이스 모델링 부분은 웹 애플리케이션을 개발하면서 모델링 하기에 가장 껄끄러운 부분이 아닌가 생각된다. Jim Conallen은 그의 저서 『Modeling Web Application Architectures with UML(2002)』에서 웹 인터페이스 모델링을 자세히 설명하고 있다. 한마디로 요약하자면 웹 애플리케이션 모델링을 위한 다양한 '스테레오 타입'을 만들어 냈다.
필자가 보기에는 실무 프로젝트에서 과연 이런 노가다 작업을 할 필요가 있을까 생각이 되지만 순수 모델링 관점에서 볼 때 웹 페이지를 모델링 하기 위한 작업으로서 의미는 있다고 본다. <그림 9>는 그가 제안한 웹 페이지를 모델링 예제이다. 참고하기 바란다.
![]() |
<그림 9> Jim Conallen이 제안한 웹 인터페이스 모델링 예 |
실무 프로젝트에서 Jim Conallen이 제안한 방법으로 모델링 하는 경우를 본적은 없고 필요한 부분만을 발췌해 많이 단순화시킨 형태로 모델링을 진행한다. 사용자 인터페이스 모델은 화면 흐름, 참여 화면의 설명, 화면 이동 맵, 화면 클래스 다이어그램, UI 프로토타입 등으로 구성된다. 이중 UML로 모델링 하는 몇 가지를 소개하겠다.
화면 흐름
화면 흐름의 경우 비즈니스 로직 처리와는 전혀 관계없이 오직 해당 작업을 수행하기 위한 화면 관점에서 모델링을 한다.
![]() |
<그림 10> 시퀀스 다이어그램으로 표현한 화면 흐름도 |
화면 이동 맵
화면 이동 맵은 각 화면의 구성 요소를 클래스 다이어그램으로 표현한 것이다.
![]() |
<그림 11> 클래스 다이어그램으로 표현한 화면 이동 맵 |
웹 애플리케이션을 위한 프레임워크 모델링
자바를 이용하여 웹 애플리케이션을 개발하게 되면 우선 여러 제약 사항들이 나타나게 된다. 앞서 이야기한 페이지 제어 문제, 세션 처리 문제, 데이터 처리 문제, 다양한 프로토콜의 처리 문제, 까다로운 보안 문제, 웹과 분산 컴포넌트간의 동적 호출 문제, 예외처리 문제, 웹 애플리케이션과 레거시(legacy)와 인터페이스 문제 등 각 메커니즘에 관해 다루어야 할 부분이 많다. <그림 12>는 각 메커니즘을 고려한 일반적인 웹 애플리케이션의 시스템 구성도이다.
![]() |
<그림 12> 일반적인 웹 애플리케이션의 시스템 구성도 |
이 그림에서 메커니즘으로 정리해야 할 주요 부분은 여러 가지가 있지만 그 중에서 Web Server와 Web App Server와의 연동 부분으로 JSP에서 어떠한 Action을 통해 EJB 비즈니스 컴포넌트를 수행시키고자 하는 부분과 데이터 처리하는 부분, 타 시스템과 인터페이스 기술을 만약 웹 서비스로 할 경우 웹 서비스 클라이언트와 웹 서비스 서버간의 메커니즘 등을 들 수 있다. 몇 부분에 대한 메커니즘에 대하여 모델을 보면서 살펴보자.
JSP에서 Action을 통해 비즈니스 컴포넌트를 수행하는 부분
이 부분의 경우 프리젠테이션 레이어와 비즈니스 레이어간의 느슨한 결합을 지원하기 위해 J2EE 패턴 중에 '비즈니스 델리게이트 패턴(business delegate pattern)'을 사용할 수 있다. 원래 비즈니스 델리게이트 패턴은 비즈니스 서비스 컴포넌트와 일어나는 복잡한 원격 통신에 관련된 사항을 클라이언트로부터 숨기기 위해 사용한다. 비즈니스 델리게이트에 관해 자세한 것을 알고 싶으면 자바 웹 사이트나 코어 J2EE 패턴을 참고하면 된다.
다음에 소개할 프로젝트의 상황 때문에 약간 변경이 되었는데 비즈니스 델리게이트는 원격 통신에 관한 처리와 함께 해당 프로젝트의 사정으로 EJB 비즈니스 컴포넌트와 일반 자바 클래스 형태의 비즈니스 컴포넌트, 그리고 웹 서비스를 통해 타 시스템의 비즈니스 컴포넌트도 함께 수행해야 했다.
따라서 비즈니스 컴포넌트가 EJB건 일반 자바 클래스건 SOAP 기반의 통신이던 간에 클라이언트는 그저 비즈니스 컴포넌트 아이디와 비즈니스 컴포넌트 쪽에 넘겨줘야 할 파라미터만 알고 있으면 되도록 설계하였다. 해당 비즈니스 컴포넌트는 비즈니스 델리게이트에서 리플렉션을 이용해 동적으로 수행되도록 했다.
![]() |
<그림 13> 비즈니스 델리게이트 부분의 클래스 다이어그램 |
<그림 13>에서 BusinessMapper의 역할은 XML 형태의 컨피규레이션(Configuration)로 빠져있는 파일을 읽어 웹 애플리케이션이 기동할 때 캐싱하게 된다. 이 컨피규레이션 파일에 담겨있는 정보를 바탕으로 BusinessMap 클래스가 모델의 역할을 하게 되는데 BusinessMapper는 BusinessMap을 자신이 갖고 있는 Map에 담아 갖고 있는다. 또한 BusinessMapper는 JVM상에 오직 하나만 존재해야 했으므로 '싱글턴 패턴(singleton pattern)'을 적용하였다. 이것을 실제로 구현하기 위해서 필자는 자카르타의 커먼스(commons)의 다이제스터(digester)를 이용하여 구현했다.
![]() |
<그림 14> 비즈니스 델리게이트 부분의 시퀀스 다이어그램 |
외부 시스템과 연동 부분
웹 서비스의 SOAP을 이용한 통신을 하기 위해서는 웹 서비스 RMI 리모트 인터페이스를 상속한 인터페이스를 상속한 스텁(stub)을 통해 비즈니스 컴포넌트를 수행하게 된다. 이 부분은 위에서 설명한 비즈니스 델리게이트 부분과 아주 관련이 깊은데 일반 자바 비즈니스 컴포넌트의 경우 같은 머신의 동일 컨텍스트에 존재하므로 스트럿츠 액션(Struts Action)에서 비즈니스 델리게이트를 통해 바로 부르면 비즈니스 델리게이트는 그저 리플렉션을 통해 해당 비즈니스 컴포넌트를 실행하면 된다.
하지만 웹 서비스 비즈니스 컴포넌트인 경우는 다른 머신에 존재하는 컴포넌트이므로 원격 호출에 대한 부분 동일한 방법으로 서비스의 위치를 찾아낼 수 있도록 J2EE 패턴 중에 '서비스 로케이터 패턴(service locator pattern)'을 이용하였다. 이 부분 역시 약간의 변형이 가해졌는데 다이내믹 바인딩 시간이 비교적 길기 때문에 서버에서 받아온 스텁을 웹 애플리케이션 서버 쪽에 풀(pool)을 하나 만들어 스텁을 한번 가져온 이후 풀에 넣어놓고 다음 호출부터는 풀에서 꺼내어 쓰도록 설계하였다. 필자는 이런 설계를 구현하기 위해 자카르타 커먼스에 있는 풀(pool)을 이용하였다. EJB의 경우도 이와 거의 유사하다. <그림 15, 16>은 웹 서비스 부분의 클래스 다이어그램과 시퀀스 다이어그램이다.
![]() |
<그림 15> 웹 서비스 부분의 클래스 다이어그램 |
![]() |
<그림 16> 웹 서비스 부분의 시퀀스 다이어그램 |
데이터 처리 부분
필자가 이 부분을 설계하고 구현해 놓고 보니 사실 메커니즘이라기보다는 일종의 유틸리티성의 헬퍼 클래스 성격이 짙었다. 주요 특징 중에 하나는 SQL 쿼리를 소스코드에 직접 넣지 않고 XML 형식의 파일로 뽑아내었다는 것이다. 데이터베이스를 통해 데이터를 주고받아야 하는 비즈니스 컴포넌트 입장에서는 쿼리 아이디와 Object 배열에 담긴 파라미터를 QueryHelper에 넘겨주면 쿼리를 실행하고 결과를 넘겨준다.
결과는 여러 형태로 받을 수 있는데 종류로는 Map 형태, Map의 리스트 형태, 특정 Bean 형태, Bean의 List 형태로 Object 객체에 담아 받아 올 수 있다. 필자는 이런 설계를 구현하기 위해 자카르타 커먼스에 있는 디비유틸(DBUtil)을 이용하였다. <그림 17, 18>은 데이터 처리 부분의 클래스 다이어그램과 시퀀스 다이어그램이다.
![]() |
<그림 17> 데이터 처리 부분의 클래스 다이어그램 |
![]() |
<그림 18> 데이터 처리 부분의 시퀀스 다이어그램 |
컴포넌트 모델링
컴포넌트 모델링의 과정은 컴포넌트를 식별하고 그것의 인터페이스를 정의하고 컴포넌트의 내부는 어떻게 작동하며 구현을 어떻게 할 건지에 대한 종합적인 과정이 필요하다. CBD(Component Based Development)에는 많은 이견들이 있지만 이 글에서는 현존하는 기법을 통해 컴포넌트 식별 방법을 아주 간략하게 설명하고 컴포넌트 모델링과정이 어떻게 진행되는지 궁금해 하는 독자들을 위해 각종 다이어그램을 보면서 살펴보기로 한다.
◆ Catalysis : 타입과 조인트 액션을 중심으로 상호작용을 분석하여 네트워크 다이어그램을 만들고, 결합력과 응집력을 고려한 메트릭을 만들어 컴포넌트 식별한다.
◆ 마르미III : 유스케이스/클래스 연관 메트릭을 사용하여 각 유스케이스와 관련 있는 클래스를 클러스터링 하여 컴포넌트 후보로 등록한 다음 다른 유스케이스도 분석하여 이전에 후보로 등록되었던 컴포넌트가 쓰이면 나머지 유스케이스도 활용할 수 있도록 인터페이스를 공개한다. 유스케이스/클래스 연관 메트릭을 분석하기가 좀 어려운 것 같다. 실무에서 활용 가능할지 의문시 된다.
◆ UML Components : 비즈니스 타입 모델에서 타입을 식별하고 이 타입을 관리할 책임이 있는 인터페이스를 정의한다. 식별된 인터페이스의 상호작용을 분석함으로써 서로간의 의존관계를 파악/정제하여 컴포넌트를 제안한다. 분석가의 경험에 많이 의존하는 경향이 있다.
◆ RUP : 분석/설계가 상당히 진행된 후 각 클래스를 종횡으로 묶는 방식을 취한다. 초기 컴포넌트 식별은 불가능 하다.
컴포넌트 인터페이스 정의
어찌됐던 간에 컴포넌트를 식별했으면 인터페이스를 정의한다. 이 단계에서 정의되는 컴포넌트 인터페이스는 Business Facade의 성격으로 각 인터페이스를 명세화 한다.
![]() |
<그림 19> 컴포넌트 인터페이스 |
컴포넌트 내부 설계
컴포넌트 내부 설계는 앞에서 정의한 인터페이스를 구현하기 위한 설계를 일컫는다.
![]() |
<그림 20> 컴포넌트 내부 설계 클래스 다이어그램 |
EJB 컴포넌트 설계
EJB 컴포넌트 자체에 관한 설계로 <그림 21>은 Customer 비즈니스 컴포넌트의 워크플로우를 관리하고 클라이언트 요청에 대해 Facade 역할을 수행하는 Stateless Session Bean 에 대한 클래스 다이어그램이다.
![]() |
<그림 21> EJB 컴포넌트 설계 클래스 다이어그램 |
유능한 모델러로 거듭나기
지금까지 개발 프로세스 측면에서 바라본 모델링과 자바 웹 애플리케이션을 위한 모델을 보았다. 사실 아주 많은 내용을 한정된 페이지에 집어넣으려고 하다 보니 주마간산 격이 되어버렸는지도 모르겠다. 모델링이라는 것이 개인적인 주관과 경험에 많은 영향을 받는 것은 사실이다.
필자는 지금까지 모델링과 관련된 프로젝트와 교육을 여러 번 해보았지만 아직까지 잘된 모델링은 바로 이런 것이라고 꼭 집어 이야기하기 힘들다. 다만 어떤 모델은 보면 왠지 푸근하고 어떤 모델은 왠지 어색하다는 느낌이 든다. 그 느낌이 뭐라는 것도 아직 정확히 모르겠지만 말이다. 모델링을 잘 하기 위해 어떻게 트레이닝을 해야 할까라고 고민하던 중에 필자가 겪었던 짧은 경험이 떠올랐다.
올해 여름에 비슷한 일을 하는 사람들과 함께 어느 업체에 방문했던 적이 있었다. 날씨는 아주 더웠지만 차 안은 에어컨을 켜서 시원했다. 문제는 주차장에 차를 세워놓고 몇 시간 동안 뜨거운 여름 뙤약볕 아래 차를 세워놔야 하므로 일을 마치고 돌아올 시점에는 차 안이 불가마 찜질방 수준으로 될 거라는 것은 충분히 예상할 수 있는 상황이었다. 그때 누군가 “그늘 아래 세워놔야 할 텐데”라고 하자 어떤 사람이 “그늘 오리엔티드(Oriented)구먼”이라고 응수했다. 그러자 또 누군가 “오리엔티드는 아니지, 오리엔티드는 왠지 그늘 자체가 되어야 하는 듯한 느낌을 준다고, 그늘 드리븐(Driven)이 맞지 않을까? 드리븐은 목표를 향해 돌진하는 느낌을 주자나? 결국 우리는 지금 그늘을 찾아가고 있는 거고”라고 했다. 이때 필자는 “음~ 정확히 말하자면 그늘 베이스드(Based)가 어울릴 것 같은데? 우리는 그늘을 베이스로 깔고 앉아야 하잖아?”라고 주장하여 모두들 웃으며 짧은 말장난을 했던 기억이 있다.
예로 든 이야기에서 그 상황에 오리엔티드(Oriented)나 드리븐(Driven), 베이스드(Based)라는 용어의 의미에 정확하게 맞았는지는 일단 논외로 하겠지만 실제 모델링을 하는 상황에서는 이와 같은 일들이 자주 일어난다. 모델링을 하는 사람들은 그 상황에 맞는 의미를 정확히 파악하여 모델을 만들기 위한 노력을 끊임없이 해야 하고 특히 용어, 단어의 의미, 그리고 단어간의 관계에 대하여 고민해보고 정확하게 짚고 넘어가는 버릇을 들여야 하지 않을까 싶다.
우리가 지금 주제로 이야기하는 UML을 이용한 모델링이라는 것이 결국 모호성이 아주 높은 자연 언어를 몇 개의 모델링 요소로 표현하는 작업이기 때문에 소프트웨어 모델링을 할 때만 모델에 대하여 생각하는 것이 아니라 실생활 속에서 패러다임에 맞게 사고하는 지속적인 훈련을 해야만 한다.
앞에서 MDA에 관하여 짧게 언급 했지만 아마 앞으로 소프트웨어 개발에 있어서 모델은 점점 더 중요한 요소로 부각될 것이다. 필자도 그렇고 이 글을 읽는 독자 여러분도 지속적인 수련을 통해 더욱 유능한 모델러로 거듭나리라 믿는다.@
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
[UML 제대로 알기] ⑤ 표준 넘나드는 UML의「적절한 사용」 (0) | 2007.09.27 |
---|---|
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드 (0) | 2007.09.27 |
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
[UML 제대로 알기] ① 가능성·확장성 품고 등장한 UML 2.0 (1) | 2007.09.27 |
[UML 2.0] Unified Modeling Language version 2.0 (0) | 2007.09.27 |
2007. 9. 27. 21:27 IT 자료/소프트웨어 공학
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML
김상훈 (동명정보대학 정보기술원 연구원) 2005/03/22
연재순서 1회. 가능성·확장성 품고 등장한 UML 2.0 2회. 초보자를 위해 다각도로 살펴본 UML 3회. 바로 알고 제대로 쓰는 UML 실전 모델링 4회. 닷넷 환경에서 UML 툴 활용 가이드 5회. 표준을 넘나드는 UML의 적절한 사용 |
몇 년이 지난 후, 필자도 객체지향이라는 무림 강호에 몸을 던지지 않을 수 없는 시점에 이르러서, 그 몇 년 전에 들었던 UML이라는 것이 무림에 출사표를 던지기 위한 필수 무공이었다는 사실을 깨달았다. 그리고 그 이름도 원망스러운 디자인 패턴!
비주얼 베이직이라는 한물간 초식에서는 ‘꽤’ 강자라고 생각했던 필자는 객체지향이라는 드넓은 무림에 발을 들여서는 초고수가 되어야 되겠다는 결심을 했고, 높은 내공을 쌓기 위한 필수 비급이라는 UML과 디자인 패턴을 익히기 시작했다. 그러면서 필자가 느낀 것은? ‘초고수는 아무나 하는 것이 아니구나’하는 것이었다.
필자는 디자인 패턴에 한이 맺힌 사람이다. 디자인 패턴을 며칠 밤씩 새워 가면서 공부할 때 느낀 고통은 이루 말할 수 없다. 가끔씩 감동을 느낄 때도 있었지만 대부분의 경우가 이해하기 힘들고 패턴에 따라 프로그램을 작성하기는 더 힘든 경우가 많았다.
결국은 객체지향에 대한 기초 지식이 부족하기 때문이라는 사부님의 조언을 듣고는 HTDP와 SICP 등의 패러다임 입문서, 리스코프나 메이어 등의 객체지향 이론서 등을 짧은 영어 실력에 열심히 번역하며 읽었다. 객체지향 디자인을 제대로 이해하기 위해서는 UML은 필수사항이었고, UML에 관련된 책도 열심히 사서 읽었다. 그때부터 필자의 머릿속에는 이상한 고정 관념이 생기기 시작했다.
"디자인 패턴도 모르는 개발자가 무슨 개발을..."
"UML은 자유롭게 쓸 수 있어야 개발을 한다고 할 수 있지..."
결국은 내공이 좀 쌓이고, 디자인 패턴과 UML을 어렵지 않게 응용해서 프로그램을 짤 수 있는 수준이 되었을 무렵에, 필자는 병적으로 디자인 패턴과 UML에 집착하기 시작했다. 래쇼날 로즈 등의 케이스 툴을 사용해 설계를 하고 있으면, 화면에 보여 지는 여러 예쁜 아이콘들을 보면서 ‘아, 나는 살아 있구나’하는 존재의 가치를 느끼곤 했다.
그렇게 열심히 익힌 기술들을 이용해서 프로그램을 열심히 개발하던 어느 날 밤, 필자는 어떤 의문을 가지게 되었다. 왜 내가 동작하는 코드를 개발하지 않고 그림을 그리고 있을까? 프로그램을 작성하는 목적이 잘 동작하는 프로그램을 작성하는 것이지 출력해서 벽에 걸어놓을 미술 작품을 만들고자 하는 것이 아니지 않은가?
필자는 플라톤의 동굴의 비유에 비견될 만한 엄청난 진리를 깨달았다. UML이든, 디자인 패턴이든 꼭 필요한 부분에만 사용하면 되는 것이고, 프로그램을 작성하기 전 개념을 잡거나 최종적으로 정리하는데 유용한 도구, 특히 UML은 개발자들 간의 상호 커뮤니케이션에 아주 유용한 도구가 될 수 있다는 것을 알게 되었다.
필자는 UML 케이스 툴을 만드는 업체에 근무하는 개발자 몇 명을 잘 알고 있다. 대학원에서 꽤 실력을 쌓아 어렵게 취업한 후배들인데, 업체에 근무한지 3개월쯤 되면 이런 말을 한다.
"UML에 이렇게 많은 것들이 있는 줄 몰랐어요. 무척 힘드네요"
1년쯤 근무하면 이런 말들을 한다.
"개발자라면 UML은 반드시 알아야죠. UML의 구석구석을 모르고 어떻게 제대로 된 프로그램을 작성할 수 있습니까?"
3년쯤 근무한 후배는 이런 말을 한다.
"UML요? 꼭 쓸데만 쓰면 되지 오버해서 쓰면 나중에 감당 못하죠"
악순환의 반복이랄지, 디자인 패턴과 UML이 남긴 폐해랄지, 이런 현상은 매년 계속된다.
아키텍트 입장에서 UML
필자가 조선 업계에서 근무할 때, 새로운 시리즈를 시작할 경우(배는 하나의 설계로 여러 척을 찍어낸다) 먼저 모형을 만들어서 테스트를 하는 것을 본 적이 있다. 모형을 만들어 수영장 같은 곳에서 테스트를 해 보고 실제로 배가 목표한 만큼의 성능을 낼 수 있는지 테스트 한다. 또한, 배를 설계할 때 거대한 캐드 시스템으로 설계한 후 파도와 바람 등에 견딜 수 있는지를 테스트한다.
배를 만들 때는 엄청난 비용과 시간이 소모되기 때문에 모형을 만들거나 컴퓨터상에서 수치로 테스트한다. 컴퓨터로 만들건, 정말 모형을 만들건, 그렇게 만들어진 것을 모델이라고 하고, 대부분의 경우 모형을 만드는 비용이 실제 배를 만드는 것보다 비용이 훨씬 적게 소모되므로 모델 테스트를 한다. 이런 모델을 만들어 테스트 해보는 과정을 ‘모델링’이라고 부른다.
배를 지을 때도 선실의 세부 구조나 엔진의 동작들은 모델링하지 않는다. 모델링이라는 것은 어떤 것이 실제로 잘 동작하는지를 알아보려고 만드는 것이다. 실제 크기대로 배를 지어 바다에서 항해해 가며 파도와 바람의 영향을 최소화하거나 풍랑에 버틸 수 있을지를 테스트 해 본다는 것은 비용이 너무 많이 드는 일이다. 모델을 만드는 이유는 모델을 만드는 비용이 실제 물건을 만드는 것보다 훨씬 적은 비용으로 설계가 제대로 되었는지 알고 싶어서이다.
소프트웨어를 만들 때도 이와 같은 이치가 적용된다. 하지만 소프트웨어를 설계할 때 사용하는 이 UML이라는 것은 조선 엔지니어나 토목 엔지니어들이 모델링을 하기 위해 사용하는 미니어처나 캐드 모델과 비교해 볼 때 훨씬 비효율적이고 테스트하기 곤란하다. UML 다이어그램에는 다른 공학 모델과 비교해 보았을 때 확고한 시험 기준을 세우기도 곤란하고 평가를 내릴 때도 주관적인 관점이 상당부분 차지할 수 밖에 없다.
조선이나 건축에서 모델을 만드는 것은 실제 배나 건물을 짓는 것과 비교할 때 비교도 할 수 없을 만큼의 적은 비용이 들지만, 소프트웨어를 설계하는 입장에서 실제 프로그램을 작성하는 것과 UML을 사용한 설계를 비교했을 때 비용적인 측면에서나 생산성적인 측면에서나 그렇게 차이 나지 않는다.
사실, UML을 사용해서 테스트하는 것보다 소스코드를 직접 수정하는 것이 비용이 훨씬 적게 들고 손쉬운 경우도 있다. 개발자의 입장에서는 더욱 그러하다. 하지만 UML을 사용해야 하는 이유는 무엇일까? 잘 사용하면 비용 절감의 효과를 가져 올 수 있고, 포괄적인 설계가 가능하다는 것이다.
UML 다이어그램이라는 것은 앞서 이야기 했듯이 다른 공학에 비해 모델을 사용했을 때 실제 건축물(소프트웨어에서는 실제 동작하는 코드)을 작성하는 것보다 비용이 명확하게 절약되는지가 명확하지 않다. 필자는 실제 프로그램을 작성하는 것보다 UML 다이어그램을 작성하는 것이 훨씬 시간이 많이 드는 경우를 허다하게 봤다(사실 그렇게 하지 않으면 제대로 된 프로그램이 나오지 않는 경우가 대부분이다).
UML 다이어그램은 세부적인 설계를 하기 보다는 포괄적인 설계를 구성하였을 때 그 전체적인 비용의 절감 효과를 가져 올 수 있다. 세부적인 그림을 UML 다이어그램으로 표시하기 보다는 전체적인 그림을 UML 다이어그램으로 표시하고 세부적인 표현은 코드로 작성하는 등의 탄력성 있는 설계 운영이 전체를 UML로 설계하는 것보다 훨씬 나은 효율을 가져올 수 있다는 것이다.
실제로 아키텍트들의 설계는 이러해야 한다. 아키텍트들은 UML 다이어그램을 세부적으로 표현하기 보다는 전체적인 그림을 그리고, 그린 그림이 실제 소프트웨어로 동작했을 때 바르게 동작할 수 있을 것인지를 개발자들과 토론하고 설계를 수정한다.
필자는 프로젝트를 시작할 때 전체 소프트웨어의 요구사항을 격자 형태로 나누고 각 부분을 개개의 개발자들에게 할당하는 경우를 본 적이 있다. 큰 부분으로 나뉜(이 큰 부분으로 나누는 것조차 PM급의 아키텍트가 하지 않는다. 그러한 큰 부분은 대 부분의 기업형 응용 프로그램이라면 부서별 또는 업무별로 자연스럽게 할당되어 있기 마련이다) 업무 분할대로 각 개발자가 ER-Diagram부터 클래스 다이어그램, 컴포넌트 다이어그램까지 작성하는 경우를 실제로 본 적이 있다.
큰 수정 없이 프로젝트가 진행되어 다행이었지만, 한 부분이라도 어긋난 부분이 있었다면 엄청난 비용이 소모되었을 것이다(사실 그렇게 작성된 프로그램은 전체적인 소프트웨어의 부품이 유기적으로 동작하는 소프트웨어가 아니고 각 부품이 각기 따로 동작하는 작은 프로그램들의 집합일 수밖에 없고, 실제로도 그러했다).
개발자 입장에서 UML
자, 이제 개발자 입장에서 UML을 생각해 보자. 실제로 개발자가 UML 다이어그램의 모든 부분을 다 알아야 하는가? 개발자가 프로그램을 작성하기 위해서 UML의 메타 모델을 모조리 이해하고 각 프로젝트와 다른 케이스 도구들에서 쓰이는 스테레오 타입들을 다 알아야 한다는 것이다.
필자는 여기에 반대한다. 필자는 주로 닷넷 기술들을 가지고 소프트웨어를 작성하고 강의하고 컨설팅을 수행하는데, 사실 닷넷 기술은 너무 빠른 속도로 변화하고 있다. 곧 출시될 비주얼 스튜디오 2005와 MS-SQL 서버 2005는 닷넷 프레임워크 2.0을 기반으로 하는데, 닷넷 프레임워크 2.0은 1.1 버전과는 상당히 다른 모습을 보여준다.
C#이나 비주얼 베이직 닷넷 같은 언어적인 측면에서만 봐도, 겉으로 보기에도 제네릭(Generic)이 포함되는 등 상당히 많은 부분이 변하였다(필자는 이 부분에서 상당히 불만이 많다. MS는 이런 부분을 발표만 하고는 다른 이야기가 없다.
여러 잡지에 소개되는 글들을 봐도 이런 기능들이 추가되었다. 이런 내용만 있지 실제적으로 테스트 해 볼 수 있는 코드를 제시하거나 근본적인 변화를 이야기하는 경우는 드물다). ASP.NET 2.0만 해도 ASP.NET 프레임워크가 전체적으로 변화한 부분도 몇 군데 있을 뿐더러 사용자 정의 컨트롤이 상당히 많이 추가되고 변화함으로 인해서 새로 익혀야 할 부분이 늘어났다.
ADO.NET도 마찬가지다. 개발자의 부담은 가중되고 실제적으로 필드에서 사용되어야 할 코드와 컨트롤들의 사용법을 익히는 것과 UML의 전체적인 내용을 학습하는 것 사이에서 갈등하게 된다.
디자인 패턴도 이럴 때 부담이 된다. 개발자 누구나가 디자인 패턴과 UML을 사용할 수 있어야 하고 열심히 학습해야 한다는 것은 알고 있지만, 현실적으로 당장 사용하여야 할 요소 기술과 끝이 보이지 않는 기반 기술을 사이에 두고 갈등하다 보면 당연히 당장 사용하게 되는 요소 기술 쪽으로 치우칠 수밖에 없다.
이럴 때 누군가에게 "UML을 조금 알아야 되겠는데 어떤 책을 봐야 되겠습니까?"라고 물어보면 그 누군가는 책을 산더미처럼 던져주고(보통 이런 경우에 이유 없이 원서를 권하는 경우가 많다. 안 그래도 바빠 죽겠는데 원서가 포함된 책 뭉텅이를 받은 개발자의 입에서는 욕 빼고는 나올 것이 없다) 이 책의 내용들을 거의 다 숙지해야 제대로 쓸 수 있다는 교과서의 화신 같은 이야기를 하게 된다. 사실, 이 말은 격무에 시달리는 개발자들에게 UML을 공부하지 말라는 이야기와 동일하게 밖에는 안 들린다.
개발자들은 프로젝트에 투입될 때 UML의 어떤 부분을 알아야 하는가? 사실 UP의 모든 부분을 다 안다는 것은 업무 형태와 업무량으로 볼 때 거의 불가능 하다고 볼 수 있다. 그렇다고 UML을 전혀 모르는 상태에서 개발에 투입되었다면 그 개발자의 앞길은 십자가를 지고 골고다 언덕을 오르는 예수님의 모습처럼 보일 것이 뻔하다. UML을 효과적으로 사용하기 위한 효과적인 길을 알아보자.
의사소통 수단으로서 UML
초보 개발자라면, 우선 UML의 표기법에 익숙해져야 한다. 이렇게 생긴 아이콘은 클래스고, 이렇게 생긴 화살표는 실제화고(물론 실제화를 이해하기 위해서는 객체지향을 이해하여야 한다는 원론적인 이야기를 피하기는 힘들다. 산 너머 산이다) 이렇게 생긴 화살표는 집단화이고 등의 표기법(Notation)을 익히는 것이 중요하다. 개발은 혼자 하는 것이 아니기 때문이다. UML은 개발자들끼리 설계 개념에 대한 의견을 주고받을 때 굉장히 편리한 도구로 사용될 수 있다. UML의 표기는 매우 명확한 의미를 전달해 줄 수 있다.
개발 경로로서의 UML
UML은 기업 형 소프트웨어를 작성할 때 구조의 개발 경로를 작성할 때 유용하다. PM이 이렇게 개발해라 하는 지시를 내리면 사실 그 지시라는 것은 추상화 된 개념이라서 바로 프로그램으로 옮기기가 곤란한 경우가 대부분이다. 이런 경우, 어떤 객체를 먼저 작성하여야 하고 어떤 객체는 어떤 객체에 의존하고 하는 식의 로드맵이 필요한데, UML은 이런 도구로서도 훌륭하다.
개발 경로로서 UML 다이어그램을 활용하려 한다면, 클래스 다이어그램, 객체 다이어그램, 시퀀스 다이어그램, 협력 다이어그램을 읽을 수 있고 작도할 수 있어야 한다. UML 표기법을 완벽하게 익힐 필요까지는 없을 테고, 적당히 다른 사람과 상호 통신할 수 있을 정도의 수준이면 충분하다.
스테레오 타입 등은 잘 알아야 하지 않느냐고? 처음엔 잘 몰라도 된다. "<<", ">>"가 붙은 기호는 스테레오 타입이라고만 아는 것으로 충분하다. UML이라는 것은 쓰다보면 이해가게 되어있는 아주 신기한 물건이다.
언제 다이어그램을 그려야 하는가?
UML은 도구일 뿐 그 자체가 목적이 되어서는 안된다. UML이 목적이 되는 경우도 물론 있긴 하다(대부분의 경우 UML이 목적이 되는 경우는 작성된 소프트웨어가 클라이언트 또는 감리에 의해 검수 받을 때뿐이다). UML을 남용하는 것은 소프트웨어 개발에 큰 걸림돌이 될 수 있다. 하지만 남용하지 말고 아껴서 사용한다면 큰 도움을 줄 수 있다. 예전의 ‘약 좋다고 남용 말고..."라는 표어는 UML에서 그대로 통한다.
다이어그램을 그려야 하는 경우 어떤 지침을 따르는 것이 좋을까? 모든 개발자들이 설계에서 특정한 부분의 구조를 이해해야 할 경우 다이어그램을 그리는 것이 좋다. 그림이 완벽할 필요는 없다. 모든 개발자들이 이해했다고 생각되면 그만 그리면 된다.
개발자들 간에 구조에 대한 분쟁이 일어날 경우 그림을 그리고 그림을 판독할 수 있는 중재자를 구할 때. UML 다이어그램은 아주 명확한 의미를 전달 할 수 있기 때문에 같은 생각이지만 다른 말을 통일시켜주는 역할을 할 수 있다. 새로운 아이디어를 떠올리고 그 아이디어를 주위 개발자 또는 상급자에게 칭찬받고 싶을 때 UML 다이어그램을 작성한다. 말로 떠드는 것보다 한번 보여주는 것이 200%의 효과를 발휘한다.
“백문이 불여일견”일 필요가 있을 때 UML 다이어그램을 작성한다. 그리고 마지막으로 클라이언트에게 ‘있어 보이는’ 문서를 보여줘야 할 필요가 있을 때 작성한다. 부차적인 설명이 없이도 다들 이해하리라 믿는다.@
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
[UML 제대로 알기] ④ 닷넷 환경 UML 툴 활용 가이드 (0) | 2007.09.27 |
---|---|
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
[UML 제대로 알기] ① 가능성·확장성 품고 등장한 UML 2.0 (1) | 2007.09.27 |
[UML 2.0] Unified Modeling Language version 2.0 (0) | 2007.09.27 |
[UML 2.0] OMG의 새로운 표준 UML 2.0 (0) | 2007.09.27 |
2007. 9. 27. 21:26 IT 자료/소프트웨어 공학
[UML 제대로 알기] ① 가능성·확장성 품고 등장한 UML 2.0
박경민 (화이트정보통신) 2005/03/15
연재순서 1회. 가능성·확장성 품고 등장한 UML 2.0 2회. 초보자를 위해 다각도로 살펴본 UML 3회. 바로 알고 제대로 쓰는 UML 실전 모델링 4회. 닷넷 환경에서 UML 툴 활용 가이드 5회. 표준을 넘나드는 UML의 적절한 사용 |
UML 2.0의 실로 엄청난 중요성을 미리 알고 대비할 것인지, 뒷짐 지고 좀 더 지켜볼지는 이번 글을 보고 판단해 주기를 바란다.
필자는 지난 2004년 마이크로소프트웨어 8월호에 MDA 관련 글을 기고하던 당시부터 지금까지 필자의 소속 회사가 지난 10여 년간 전문적으로 개발해 오던 인적 자원 관리(HRM) 시스템에 대한 획기적인(?) 개선 방안으로 MDA 기반의 시스템 개발을 추진하고 있다. 필자가 본격적으로 UML 2.0을 검토하기 시작한 것도 8월을 전후해서였다.
그러나 회사에서 표준으로 사용하는 모델링 도구 제작 업체에서는 4개월 전만 해도 UML 2.0을 지원하지 않았고, MDA 패러다임을 표방하면서도 아쉽게도 그 요체인 UML 2.0은 그저 각종 문서나 자료들을 통해서만 접할 수 있었다. 인사 비즈니스 프로세스 개선 작업(BPI)과 같은 초기 설계 작업은 UML 1.4 기반으로 추진해야 했고, 올 연말로 예정됐던 도구 공급사의 차기 버전을 기대해야 하는 상황이었다.
그러던 얼마 전, 필자는 해당 업체로부터 UML 2.0을 충실히 지원하게 된 새 버전의 케이스 도구를 입수했다. 비록 필자가 이미 여러 책이나 자료들을 통해 UML 2.0을 검토했었음에도, 막상 본격적으로 UML 2.0 지원 모델링 도구를 설치하고 작업을 착수하려던 그 순간의 첫 느낌을 말로 하자면 막막함 그 자체였다.
그 모델링 도구의 새로운 버전이 완전히 개편된 새로운 사용자 인터페이스로 구성됐으며 내부적으로도 상당한 기술적인 패러다임 전환이 있었던 것도 한 원인이었겠지만, 무엇보다도 근본적으로 UML 2.0이 내포한 그 가능성과 확장성에 대한 놀라움과 설렘이 교차하면서 만들어낸 미묘한 흥분과 두려움이었다는 것이 적절한 것 같다. 1620년 메이플라워호를 타고 미지의 땅 아메리카에 첫 발을 내디뎠던 이주민들의 마음이 이렇지 않았을까?
UML의 사회적 파장
UML 2.0 발표와 더불어 개발자들이 주목해야 하는 세부 내용을 살펴보기 전에 우선, UML을 중심으로 소프트웨어 업계에서 벌어지는 경제적, 사회적 현상들을 통해 향후 UML 2.0 발표 이후 소프트웨어 업계에 불어 닥칠 파장에 대해 미리 가늠해 보는 시간을 가져 보기로 하겠다.
IT 시장 변화에 주목하자
이 시대 소프트웨어 산업에 종사하는 사람이, 딴 세상에 사는 사람(beings in heaven)이 아닌 이상, 자본주의 시대를 살아가는 현대인으로서 공급과 수요를 결정하는 시장 논리로부터 자유로울 수는 없다.
우리는 종종 뛰어난 기술력을 갖추고 있음에도 망하는 반면, 특별한 기술력을 가지고 있지 않음에도 번창하는 사람이나 기업을 종종 목격하곤 한다. 즉, 기술력이 곧 성공을 의미하지는 않는다. 마찬가지 논리로, UML 2.0이 아니라 그 어떤 뛰어난 기술이 존재한다 하더라도 IT 시장에서 그 기술력을 필요로 하지 않거나 수용할 수 없다면, 그 기술력의 시장 가치는 무의미할 수밖에 없다.
2000년을 전후해서 전세계적으로 Y2K 문제가 사회적 문제로 부각되고 시스템의 대공황 사태가 예고되던 시절, 아이러니컬하게도 당시 소프트웨어 산업에서는 사양길로 접어들었던 프로그래밍 언어의 전문가들이 국내의 IMF 사태와 맞물려 고액 연봉으로 대접 받으면서 해외로 진출했던 일이 기억난다. 역시 기술의 가치(technology value)는 시장 원리(market behavior)에 의해 결정될 수밖에 없음을 인정하지 않을 수 없다.
그런 관점에서 UML 2.0이 공식적으로 공표되는 전후의 소프트웨어 산업계 판도를 살펴보는 것은 의의가 있다. 세계적으로 이미 프로그램 개발 도구 시장은 그 성장세가 둔화됐고, 모델링 도구는 빠른 속도로 보편화되어 가고 있다. 지난 몇 년간 일어났던 IT 업계의 큰 사건들을 살펴보면 그러한 사실을 쉽게 확인할 수 있다.
이를테면 예전에는 비싸게 판매하던 개발 도구를 점차 저렴하게 행사 가격으로 판매한다거나, 개발자 저변 확산이라는 명목 하에 학교나 학원을 중심으로 무료로 배포하고 있다. 심지어는 이클립스 등과 같은 막강한 개발 도구를 오픈소스로서 인터넷을 통해 무료로 배포하고 있다.
몇 년 전 세계적인 소프트웨어 업체인 MS에서는 비지오(Visio)라는 2D 전용 도구 개발 업체를 인수했고, IBM은 세계적인 모델링 도구 전문 개발 업체인 래쇼날을 인수합병했으며, 연이어 볼랜드에서는 투게더를 사들였다. 한편, 국내외 UML 관련 포럼이나 협회들에서는 앞다퉈 UML 관련 인증 제도를 만들어 발표하면서 그 인지도를 넓혀 가기 위한 대대적인 작업을 벌이고 있다.
UML 인증 제도의 필요성이라든지, 인증 제도 자체의 신빙성이나 효용성에 대해 논하기 이전에, 어떠한 사상이나 개념이 제도화 되는 과정을 거치고 있다는 사실은 그 사상이나 개념이 해당 분야에서 도입기(intro)와 성장기(growth)를 거쳐 성숙기(mature)에 진입하고 있음을 암시하는 것이다.
표준화의 숨은 뜻
UML을 논하면서 표준화(standardization)라는 키워드를 빼놓을 수 없다. UML이 발표되기 전에 국방이나 MIS 분야 엔지니어들에게 친숙한 IDEF라든지 DFD, ER 혹은 Petri nets 등과 같은 정형 기법(formal method)으로 통칭되는 수많은 표기법(notation)과 지원 케이스 도구들이 존재했음에도 불구하고(참고자료: [1]번혹은 [2]번등), UML은 가장 단기간 동안 소프트웨어 공학 분야에서만큼은 빠른 속도로 사실상의 표준(de-facto)의 위치를 확보했다. 언뜻 생각해 보면 UML이 여타 표기법들을 교통정리해 준 안도감(?)이 들 수도 있겠지만, 겉으로 잘 드러나지 않는 그 내막에는 무서운 음모(?)가 도사리고 있다.
표준화 작업에 주도적인 역할을 수행하는 업체들이 왜 그토록 천문학적인 자본을 투자하면서 공개적인 표준화 작업에 동참하는 것일까? 여러 가지 복합적인 이유들이 있을 수 있겠지만, 결론적으로 표준화 경쟁이다.
유명한 예로, 1970년대부터 시작됐던 빅터(Victor)의 VHS 방식과 소니의 베타 방식으로 대표되는 비디오 표준 전쟁을 들 수 있고, 최근에는 유럽과 미국을 중심으로 벌어지고 있는 위성방송 표준화 전쟁을 들 수 있다. 표준화 전쟁에서의 승패는 곧 기업의 운명을 좌우하는 것이다.
표준화의 이면에는 높은 진입 장벽을 통해 허가 받지 않은 침입자(intruder)를 봉쇄하려는 무서운 저의가 자리 잡고 있다. 시야를 좀 더 넓혀 보면, 의사나 판사, 회계사 등. 통속적인 표현으로 소위 ‘사’자로 끝나는 직업들에 대한 사회적 가치관을 살펴보면 쉽게 이해할 수 있다.
사람 몸을 열어서 칼질하고, 같은 인간으로서 다른 인간을 판단하고, 숫자 가지고 씨름하는 직업이 산업혁명 이전에는 별볼일 없는 직업이었다. 인류의 보편적인 가치관으로 판단하더라도 결코 즐거운 일이 될 수 없음에도 불구하고 전세계적으로 공히 가장 선호하는 직업이자 사회적으로도 가장 대접받는 직업이 된 현실에 미루어 짐작해 보면, 왜 그토록 세계적인 소프트웨어 업체들이 표준화를 통해 높은 진입 장벽을 구축하고 제도화에 전념하는지 그 이유를 충분히 이해할 수 있다.
어려운 시험을 통과하지 않고 누구라도 일정한 요건만 갖추면 수행할 수 있는 일반적인 직종 중의 하나라면 그렇게들 동경하는 직종이 됐겠는가? UML 2.0이 경제적으로나 사회적으로 주목 받는 이유 중의 하나는 바로 그러한 맥락에서 비전문인과 전문가를 구별하는 높은 장벽(?)을 쌓을 수 있는 재료(material)를 확보하고 토대를 마련했다는 점에서 의의가 있는 것이다.
주목해야 할 UML 2.0의 핵심 메커니즘
1997년 11월 UML 1.1로 시작된 OMG의 표준화 노력은 2001년 5월 UML 1.4 발표와 더불어 부분적인 개정 작업(minor version upgrade)의 막을 내리고, 대대적인 수술 작업을 거쳐 2004년 연말을 전후로 드디어 그 실체를 드러내었다.
그 동안 쟁쟁한 세계적인 소프트웨어 벤더들간의 보이지 않는 이해 관계(?)에 얽혀 2002년 말로 예정됐던 최종 발표 시한을 2년여를 연장하면서 이제서야 그 대단원의 막이 마무리되고 있다. 향후 UML 2.0의 일정은 명실상부한 국제 표준(de jure)으로 자리매김하기 위해 ISO 설계 표준으로 추진 중인 것으로 알려져 있다.
UML 2.0이 주목 받는 가장 중요한 이유는 무엇일까? 처음 세상에 나오고 나서는 여기저기서 수많은 비판을 받았지만, 그것은 UML이 어떠한 플랫폼이나 도메인에도 의존하지 않고 소프트웨어 개발의 전 공정(SDLC)을 지원하는 방향으로 지향해왔다는 데에 그 원인을 찾을 수 있다. 즉, 요구사항 획득으로부터 마지막 테스트까지 모두 지원하는 표기법으로서 진화해 왔다는 것이다.
그리고 점진적으로 UML 2.0부터는 실행 모델(executable UML)이라는 기법을 수용함으로써, 소프트웨어 공학에서 궁극적으로 염원하던 분석 설계(analysis & design)와 실제 구현(implementation) 간의 차이(chasm)를 극복하는 성과를 보였기 때문이다.
OMG의 UML 2.0에 대한 제안요청서(RFP)의 주제이자 현재 채택된 명세서 초안은 크게 4가지의 영역으로 분류된다. CASE 도구 벤더들간의 모델 호환성 문제를 다루고 있는 다이어그램 호환(Diagram Interchange) 영역과 모델 수준에서의 요소(elements) 제어 및 제약 문제를 다루고 있는 OCL(Object Constraint Language) 영역, UML뿐만 아니라 OMG가 주관하는 각종 표준의 통합과 정의에 활용되는 메타 모델 수준의 기본 구조체(constructs)를 명시하고 있는 하부구조(Infrastructure), 그리고 메타 모델을 기반으로 사용자 수준에서 모델을 활용하여 시스템의 구조(structure)와 행위(behavior)를 정의하고 있는 14개의 다이어그램을 정의하고 있는 상부구조(Superstructure)로 분류할 수 있다.
UML 2.0의 본질을 제대로 이해하려면 핵심인 하부구조로부터 차근차근 살펴보는 것이 순서이겠지만, 지면과 주제를 고려할 때, 일반인들이나 설계자들이 UML 2.0을 처음 대면하는 경우 가장 먼저 관심을 가지게 되는 UML 구조체(user-level constructs)인 상부구조로부터 이야기를 풀어가는 방식을 택하기로 하겠다.
![]() |
<그림 1> UML 2.0 표준 다이어그램 |
상부 구조는 크게 6개의 다이어그램으로 구성된 구조형 다이어그램(Structural Diagram)군과 7~8개의 다이어그램으로 구성된 행위형 다이어그램(Behavioral Diagram) 군으로 분류할 수 있는데, 각 군의 대표적인 복합 구조 다이어그램(Composite Structure Diagram)과 순차도(Sequence Diagram)를 중심으로 그 특징과 의의를 살펴보도록 하겠다.
이어서 UML 2.0의 기반을 설명하고 있는 하부구조의 의미는 무엇인지, 그리고 실제 설계 작업에서 하부구조의 접근법은 어떠한 방식으로 활용하게 될 것인지 논의하기로 하겠다.
상부구조 - 구조형 다이어그램
일명 아키텍처 다이어그램(architectural diagram)이라고도 불리는 복합 구조 다이어그램(composite structure diagram)은 UML의 핵심 다이어그램인 클래스 다이어그램의 변형된 형태이다. 이는 시스템 구조 설계에 있어 또 다른 핵심 축으로 평가 받고 있으며 가장 주목 받는 다이어그램 중의 하나이다.
복합 구조 다이어그램은 기본적으로 시스템 혹은 컴포넌트의 내부 구조(internal structure)를 명시적으로 중첩시켜 표현하고 있으며, 시스템 아키텍처의 보다 섬세한 분석과 설계 사상을 담을 수 있게 된 점이 가장 큰 매력으로 꼽을 수 있다.
그렇다면 왜 복합 구조 다이어그램이 주목받는지, 그리고 복합 구조 다이어그램은 왜 탄생하게 되었으며, 향후 어떠한 용도로 활용하게 될까? 보는 시각에 따라 의견을 달리 할 수 있겠지만, UML 1.x은 근본적으로 OOAD 수준의 설계 사상을 표현하기에 최적화된 표기법으로 평가되어 왔다.
UML 1.x에도 비록 컴포넌트 다이어그램이라는 것이 있기는 했지만, 실제 너무 빈약한 문맥(semantics)으로 인해 별로 활용되지 못했으며, 강경한 컴포넌트 신봉자들이나 대용량 시스템 혹은 전체 시스템을 통합적으로 표현하기 원했던 아키텍처 전문가 진영 개발자들에게는, 그저 객체 옹호론자들이 제시하는 옹색한 명분(?)에 지나지 않았다. 사실 UML 1.x 자체에도 명시하고 있듯이, 컴포넌트 다이어그램은 몇몇 다이어그램들과 더불어 클래스 다이어그램에 일종의 간단한 확장 메커니즘을 통한 단순한 관점(view) 변경 수준에 지나지 않았다.
비즈니스 컴포넌트에 관심이 많았던 컴포넌트 신봉자들의 경우, UML 1.x의 스테레오타입(stereotype)등의 확장 메커니즘을 통해 그럭저럭 UML 1.x과의 관계를 유지하면서도 BPM이라는 포괄적이고 확장된 별도의 비즈니스 컴포넌트 표기법을 병행하며 UML 1.x의 미비한 부분을 채워 나갔다.
아키텍처 전문가 진영에서는 상황이 조금 달랐는데, 대다수의 아키텍처 전문가 진영에서 관심을 가지고 있던 임베디드 혹은 리얼타임 도메인에서는 단순히 UML 1.x 정도의 확장 메커니즘으로는 그들이 필요로 하는 아키텍처를 통한 시뮬레이션 등과 같은 시스템의 섬세한 분석 및 설계라는 목적 달성이 거의 불가능했고, 그러한 목적 달성을 위해 UML의 확장 메커니즘을 활용한다는 것은 차라리 자신들만의 특정 영역에 필요한 표기법을 자체 정의하여 사용하는 것이 훨씬 경제적이었다는 것이다.
왜냐하면 이미 아키텍처 전문가 진영에서는 UML 1.x가 발표되기 이전에 광범위하게 수많은 ADL(Architectural Description Language)과 관련 시뮬레이션 도구들이 개발되어 활용되고 있었으며, 굳이 UML에 순응하는(compliant) 방안을 모색하기 위해 UML을 연구하고 고민할 시간적 여유나 명분이 없었던 것이다.
그러나 그러한 두 진영에서 근본적으로 해결하지 못한 결정적인 문제는 자신들이 독자적으로 발전시켰던 표기법 중에 어떠한 것도 명실상부한 사실 표준(de-facto)으로 합의하지 못했다는 것이다. 가령, 아키텍처 전문가 진영에서 필요로 하는 시스템 시뮬레이션 기능을 구현하는 데 사용하는 정형 기법의 경우 동일한 도메인에서조차 연구소나 익숙한 기법에 따라 서로 달리 정의하고 필요한 시뮬레이션 도구를 개발해야 했다.
국제적인 공동 작업은 말할 것도 없이 국내에서 서로 다른 연구기관이 공동 작업을 수행하기 위해서도 사전에 일정한 표준 정형 기법을 합의하고 정립한 후 과제를 수행해야 했으며, 최종적으로 통합하는 과정에서는 결국에 모델 수준에서의 통합을 포기하고 구현 수준에서 테스트를 통해 통합하는 방식을 따라야 하는 문제점을 내포하고 있었다.
덧붙여 두 진영에서 해결하지 못한 결정적인 문제 중의 하나는 실제 구현(code)에 필요한 낮은 추상화 수준의 설계에 대해서만큼은 어설픈 UML 1.x의 메커니즘만한 수준의 방안을 제시하지 못했다는 것이다.
UML 2.0에서 새롭게 등장한 복합 구조 다이어그램은 바로 지금까지 앞서 살펴 본 아키텍처 전문가 진영으로 대표되는 임베디드 혹은 리얼타임 도메인의 핵심 개념이자 도구였던 SDL(Specification Description Language)을 수용하여 탄생한 다이어그램이다.
![]() |
<그림 2> UML 2.0 복합 구조 다이어그램 예 |
UML을 잠시라도 살펴 본 경험이 있는 개발자들이라면, 복합 구조 다이어그램의 개략적인 형태만을 보고서도 쉽게 그 특징을 이해할 수 있을 것이다. 즉, 복합 구조 다이어그램은 매우 직관적인 형태를 취하고 있으며, 기존의 UML 1.x에서 단순한 패키지 개념의 서브시스템 내부를 구성하고 있는 클래스 다이어그램으로만 표현이 가능하던 시스템 내부 구조를 보다 섬세하게 설계할 수 있게 됐다.
그렇다고 <그림 2>와 같이 대부분의 UML 2.0을 기반으로 한 샘플들처럼 임베디드나 리얼타임 도메인과 같이 상대적으로 소프트웨어의 비중이 작은 단위 시스템이나, 특정 MIS 분야의 단위 서브시스템의 내부 설계에만 국한되어 복합 구조 다이어그램을 활용하겠다고 생각한다면, UML 2.0의 본질을 제대로 이해하지 못하고 있는 것이다.
복합 구조 다이어그램의 형태는 앞서 언급한 아키텍처 전문가 진영에서 아키텍처를 표기하는데 가장 많이 활용하는 아키텍처 스타일인 C&C(Component & Connector) 뷰 타입(view type)과도 일맥상통하는데, 복합 구조 다이어그램을 활용하고자 하는 모델의 추상 수준을 높이면 대규모 시스템의 아키텍처도 매우 유용하게 설계할 수 있게 된다.
<그림 2>에서 벤딩머신(VendingMachine)으로 되어 있는 부분을 인사시스템이라 정의하고 내부 부분(parts)들을 그것을 구성하고 있는 단위 시스템으로 정의하게 되면, 외부 인터페이스를 통해 회계시스템(AS)이나 고객관리시스템(CRM) 등과 주고받아야 할 데이터나 정보를 명시적으로 설계에 반영할 수 있을 것이다.
바로 설계자가 의도하는 어떠한 추상화 수준의 모델이라도 UML 2.0의 복합 구조 다이어그램은 보다 섬세하게 설계할 수 있도록 일관된 문맥(context)과 의미(semantics)를 제공하고 있는 것이다.
상부구조 - 행위형 다이어그램
UML 2.0 상부구조 중 구조형 다이어그램은 말 그대로 구조적인 혁명을 꾀했다면, 행위형 다이어그램 군에서는 시스템의 동적 설계를 제대로 반영하기 위해 기존의 행위형 다이어그램 군 소속 다이어그램의 의미(semantics)를 보강하고 정제함으로써, 진화 방식을 선택했다는 표현이 적절할 것 같다.
그 근거로서 앞서 복합 구조 다이어그램으로 대표되는 구조형 다이어그램에서 수용한 SDL의 경우와는 다르게 UML 1.x에서 이미 수용하던 MSC(Message Sequence Chart) 개념을 UML 2.0에 와서는 전폭적으로 수용하여 순차도(Sequence Diagram)를 중심으로 행위형 다이어그램들의 유기적 결합 통로를 확보함으로써 시스템의 모델 수준에서의 논리적인 실행을 그대로 설계에 반영할 수 있는 발판을 마련했다.
![]() |
<그림 3> UML 2.0 순차도의 예 |
<그림 3>에서 보는 바와 같이 UML 2.0 순차도의 가장 두드러진 특징은, 기존의 UML 1.x에서 지원하지 못했던 시스템의 분기, 참조, 병렬 실행 등과 같은 세세한 부분들까지도 지원이 가능하도록 중첩된(nested) 표기법 체계를 설계 기법으로 도입했다는 사실이다.
MSC와 같은 기법에 익숙한 개발자들에게는 언뜻 보기에 별로 특이할 것이 없어 보일지 모르지만, 중요한 사실은 UML 2.0을 표준 표기법으로 수용함으로써 어떠한 비즈니스 도메인이나 기술 영역에서도 <그림 3>의 순차도 뿐만 아니라 UML 2.0의 다른 다이어그램들과 유기적인 연결고리를 가지고 활용함으로써 거의 무한대에 가까운 표현 수단을 확보할 수 있다는 사실이다.
UML 2.0 상부구조 중 행위형 다이어그램의 갱신에 대해 많은 관심을 가지는 사람은 임베디드 혹은 리얼타임 진영에 종사하고 있는 개발자들이겠지만, 기존의 비즈니스 프로세스 모델링 분야에서 종사하던 개발자 진영도 깊은 관심과 기대를 가지고 있다.
필자 또한 비즈니스 프로세스 모델링과 관련하여 행위 형 다이어그램의 특성과 최적 방안을 모색하고 있는데, 동일 비즈니스 도메인에서조차 개별 기업마다 그 특성과 비즈니스 프로세스 처리 방식이 천차만별인 문제를 해결하고자 등장했던 워크플로우 엔진 혹은 설계 시스템(workflow engine or system)과 같은 전문적인 도구의 기능을 충분히 대치할 방안이 마련된 것으로 평가되고 있다.
하부구조 - 메타 모델
소프트웨어 공학 분야에서는 이런 속설이 있다. 자신의 분야에서 메타 모델 기반의 접근을 하게 되면 하나의 논문이 된다. 매일 고객들과 씨름하면서 현장에서 일하는 개발자들에게는 먼 나라 이야기처럼 들리고, 현실적으로는 일정 규모의 연구소 혹은 학교에서나 다루어질 만한 주제로 치부됐던 것이 사실이다.
UML 2.0 하부구조(Infrastructure)는 일반적으로 UML 2.0을 지칭할 때 생각하는 UML 2.0 상부구조뿐만 아니라 OMG의 또 다른 메타 모델 집합인 MOF, CWM 뿐만 아니라 미래의 새로운 표준을 정의하기 위해 심혈을 기울여 정의한 메타 모델이다.
OMG에서 처음 메타 모델 4계층 개념을 발표했을 때에는 그저 개념적인 내용으로만 인식하지 못했지만, UML 2.0의 실체가 드러나고 그것을 지원하는 케이스 도구들의 기능들이 메타 모델 기반 설계 방식을 지원함으로써, 이제는 메타 모델이라는 주제가 현장에서조차 피해갈 수 없는 현실 문제로 다가올 것이다. 그러므로 이제는 메타 모델 4계층 개념을 충분히 이해하고 응용하는 노력을 기울일 필요가 있다.
![]() |
<그림 4> OMG 4계층 메타 모델 예 |
글의 주제와 지면 관계상 메타 모델에 대한 깊이 있는 논의를 하지는 못하지만, <그림 4>의 예로 간단히 살펴보자. 시스템 분석가나 설계자들이 일반적인 모델링 케이스 도구를 통해 특정 도메인 시스템을 설계한다고 했을 때의 메타 모델 수준(level)이 바로 사용자 모델을 도식하게 되는 M1 수준이다.
M2 수준은 그러한 UML 기반의 설계를 가능케 하는 어트리뷰트, 클래스, 인스턴스 등과 같은 모델 요소를 정의하는 메타 모델이며, UML 2.0의 하부구조는 바로 위 4계층 메타 모델 관점에서 M2 수준의 UML 메타 모델이 된다. M3 수준에 위치한 MOF(Meta Object Facility)는 M2 수준에 속한 메타 모델을 정의하는 메타메타 모델이 된다.
참고로 CWM(Common Warehouse Metamodel)은 M2 레벨이며, MOF의 내부 구조는 추상화된 UML 하부구조와 동일한 방식으로 정의하고 있다. 자세한 사항은 OMG UML 2.0 Infrastructure, 7. Language Architecture를 참조한다.
앞에서 살펴 본 바와 같이 OMG에서 UML 2.0 관련 제안요청서(RFP)를 제기한 목적은 단순히 UML 2.0을 체계적으로 정리하고자 한 것이 아니라, OMG의 또 다른 표준인 MOF와 CWM 및 미래의 새로운 표준을 체계적으로 정의하기 위한 용도로 제기됐던 것이다. 여기서 우리가 주목해야 할 사항은 UML 2.0 하부구조에 대한 제안요청서를 통해 제기한 또 다른 목적이다.
그것은 바로 지금까지 M1 수준에서 UML을 활용하던 사용자들이 보다 수월하게 M2 수준에서 UML을 커스터마이징하여 활용할 수 있는 메커니즘을 제공하는, 즉 이원화된 메커니즘을 제공하여 사용자들이 유연하게 특정 기술 도메인이나 비즈니스 도메인에 최적화된 방식으로 설계를 수행할 수 있도록 하자는 데 그 취지가 있었다.
그 핵심이 바로 UML 프로파일(UML Profiles)이다. 지금 UML 2.0 작업과 동시에 진행되고 있는 대표적인 기술 도메인 프로파일로는 우리들에게 친숙한 EJB 프로파일(Profile for EJB), 닷넷 프로파일(Profile for .Net)을 들 수 있다. 프로파일을 간단히 설명하면, 일종의 특정 기술이나 비즈니스에 적절한 커스터마이징된 확장 메커니즘을 사전 정의해 놓고, 추상화 수준이 서로 다른 모델들간의 전환(transformation)을 자동화시키는 핵심 메커니즘이다.
플랫폼 독립 모델(PIM: Platform Independent Model)로부터 특정 플랫폼 종속 모델(PSM: Platform Specific Model)로의 자동화된 전환이라는 MDA의 사상이 바로 대표적인 일례라고 볼 수 있다. UML 프로파일은 향후 MDA를 통해서 달성하려고 하는, 아니 궁극적으로 UML 2.0을 통해 달성하게 될 소프트웨어 공학의 핵심 화두인 소프트웨어 개발 생산성 향상의 핵심 메커니즘으로 평가 받고 있다.
만약 이 글을 읽는 개발자가 속한 관련 분야에 MIS 분산 시스템 개발의 사실 표준으로 통용되는 J2EE나 닷넷 등과 같은 개발 기술 표준 프레임워크가 존재한다면 다행스러운 일이다. 모델링 도구 벤더에서 제공하는 EJB 프로파일이나 닷넷 프로파일과 같은 기술 메타 모델은 그대로 활용하고, 관심 비즈니스 영역에 해당하는 표준 도메인 프로파일을 활용하거나, 독자적으로 정의해 설계 작업을 추진해 나갈 수 있기 때문이다.
하지만 최악의 경우 관련 분야에 기술이나 도메인 프로파일이 존재하지 않고, 더욱이 활용할 만한 케이스 도구조차 존재하지 않는다면 난감하다. 하지만 UML 2.0을 충분히 지원하는 범용 혹은 상용 케이스 도구를 통해 구현된 방식이나 기능을 살펴보면 놀랄 만큼 간결하다. 문제는 UML 2.0의 프로파일 방식과 같은 메커니즘을 이해하는 것이 아니라, 그 동안 개발자들이 간과해 왔던 문제, 가령 “해당 비즈니스 도메인을 제대로 이해하고 있었는가?” 등과 같은 근본적인 문제를 되돌아보는 계기가 될 것으로 생각된다.
어떻게 대처할 것인가
지금까지 UML 2.0 출시를 전후해서 전개되어 왔던 소프트웨어 산업계의 전반적인 흐름과 사회적 파장, 그리고 UML 2.0의 상부 및 하부구조의 핵심 메커니즘을 중심으로 간단히 살펴보았다. 그렇다면 과연 어디서부터 어떻게 UML 2.0을 시작할 것인가?
기본 원칙에 충실하자
우선 스스로에게 UML 1.4는 제대로 이해하고 활용해 왔는가라는 질문을 던져 보아야 한다. 필자의 경우 하는 일이 하는 일인만큼 UML 2.0이 발표되기 이전에도 자바나 비주얼 베이직 등과 같은 프로그래밍 용어나 주제에 비해 상대적으로 UML(1.x), OOAD, CBD, 방법론 등이라는 용어가 훨씬 낯설지 않았다.
당연히 주변에는 상대적으로 코딩보다는 현장에서 분석(analysis)이나 설계(design)를 전문으로 하거나, 학교나 학원 등에서 학생들을 가르치는 사람들이 많았지만 그 중에 UML 1.x 관련된 OMG 무료 명세를 제대로 살펴보았거나, 가까이 두면서 참조하는 사람은 찾아보기 어려웠다.
필자 가까이에 ‘UML 1.4 사용자 지침서’를 한글로 번역했던 분을 통해 확인해 보아도, 국내 출판사에서 출간한 책 부수로 미루어 UML 원문은 차치하고서라도 핵심 내용만을 추려서 발간한 그 UML 사용자 지침서마저 꼼꼼히 살펴 본 사람은 별로 보지 못한 것 같다. 필자도 예외는 아닌데, 돈이 없어서 혹은 원서이기 때문에라는 것은 이유가 되지 않았던 것이다.
그런데 UML 2.0이 공식 발표되는 이 시점에도 상황은 예전이나 별반 다르지 않은 것 같다. UML 2.0으로 공식 공표되기 전에 이미 오래 전부터 OMG에는 UML 관련 명세를 1.5의 형태로 인터넷에 배포하고 있었지만, 살펴본 사람은 찾기 어려웠다. UML 1.1이 처음 발표되던 시점에는 표기법으로서의 표준화 경쟁에서 판정승이 나지 않았던 때여서 그랬다고 하더라도, UML 2.0이 공표되는 이 시점에는 이미 국내외 많은 대학의 컴퓨터 관련학과에서 필수 과목으로 개설되었을 만큼 그 중요도와 필요성이 검증된 마당에 애써 그 사실을 외면하는 것은 더 이상 이유가 될 수 없다.
물론 지금까지의 현실은 그렇지 못했던 것이 사실이다. UML 전문가들마저도 UML 1.x의 설계 도구로서의 완성도가 받쳐주지 못했고, 무엇보다도 고객들도 유기적으로 논리적인 설계 모델을 기대하지 않았기 때문에 UML이라는 포장지를 가지고 피상적이고 개념적으로 대충 구색 맞추기식 설계 산출물을 만들어 주면 그만이었다.
그러나 앞으로의 상황은 그렇지 못할 것이다. 당장은 아니겠지만 UML 2.0 표기법이 소프트웨어 산업 시장에서 보편적으로 활용되고 국내외에서 하나 둘 그 무한한 잠재력과 가능성이 증명되어 그 시장 가치가 확연히 드러나기 시작하는 시점에는 우리 주변의 고객들 또한 단순히 보기 좋은 산출물 정도의 설계를 요구하지는 않을 것이다.
그렇다면 어디서부터 어떻게 준비해야 할 것인가? 그 실마리는 처음 접하면 이해하기 어렵고 복잡한 UML 2.0 관련 명세나 두꺼운 책에서 찾을 것이 아니고, 누구나 알고 있으면서도 충실하지 못했던 가장 기본적이고 원칙적인 원리를 고민하는 것부터 시작해야 한다.
원칙 하나, 도메인을 철저하게 분석하자
시스템을 설계한다고 했을 때, UML과 같은 설계 기법을 동원하여 작업하는 시스템 분석 및 설계자 그룹 외에 매우 중요한 역할을 수행하는 집단이나 개인을 가리켜 도메인 전문가 혹은 비즈니스 분석가라고 한다. 가장 이상적인 시스템 설계자는 두 가지 능력 즉, 해당 도메인에 대한 공인된 전문적인 지식을 가지고 있으면서 동시에 설계 능력을 고루 갖춘 인재일 것이다.
그러나 현장에서 그런 핵심 인재를 찾기는 어려운 것이 사실이다. IT 업계로만 보더라도 시스템 설계자와 개발자 간에 차이가 좀처럼 좁혀지지 않는데, 전혀 그 분야와 전공이 다른 비즈니스 전문가와 시스템 전문가 간에 느끼는 갈등은 말할 필요도 없다. 시스템을 설계해 본 사람은 누구라도 공감하겠지만, 시스템을 제대로 설계하려면 해당 도메인을 충분히 이해하고 철저하게 분석해야 한다. 그렇지 않으면 제대로 된 시스템을 설계할 수 없다.
시스템 설계자 입장에서 문제는 해당 도메인을 제대로 이해하기 위한 충분한 시간도 주어지지 않고, 나름대로 시스템 설계자가 충분히 이해한 것을 객관적으로 검증해 줄 만한 기준도 마련되어 있지 않다는 것이다. 설사 객관적 기준이 있더라도 그것은 현실적으로 거의 불가능하다는 것이다.
가령 회계 시스템을 설계하려면 회계사 자격증을 갖춰야 하는가? 물론 아니다. 그런데 우리는 주변에서 타의든 자의든 특정 도메인 시스템을 반복해서 설계하는 설계자의 경우 점점 해당 도메인에 대한 이해력이 높아지고, 회계사와 같은 공인된 자격증은 취득하지 못하더라도 나름대로 그 전문성을 인정받아 시장에서 높이 평가되는 경우를 보곤 한다.
비단 시스템 설계자에게만 해당되는 문제는 아니다. 조각조각 할당된 부분만 열심히 해야 하는 개발자에게도 비슷한 현상은 쉽게 찾아 볼 수 있다.
설계하고자 하는 해당 도메인에 대한 철저한 분석 없이는 일정한 추상화 수준을 유지한 유기적인 모델을 만들어 낼 수가 없다. 몇몇 책이나 발표 자료에서 설계 팁으로 이야기 하듯이 해당 도메인에서 반복적으로 등장하는 명사(nouns)를 클래스명으로 명명한다는 식으로 설계를 진행하다 보면 점점 헤어나지 못하는 미궁으로 빠져들게 된다. 결국에는 UML 2.0이라는 강력한 설계 도구를 가지고도 설계 따로, 코딩 따로라는 늪에서 벗어날 수 없다.
UML 표준화를 주도하는 OMG에 대해서 많은 사람들은 단순히 CORBA, ORB 등과 관련한 국제적인 기술 표준화 단체 정도로만 인식하고 있다. 하지만 앞서 주장한 도메인 지식 혹은 도메인 표준에 대한 중요성에 대해서는, 그러한 기술 표준화 단체로 출범한 OMG에서 2002부터 발족하여 추진하고 있는 DTF(Domain Task Forces) 위원회의 활동을 살펴보면 쉽게 이해할 수 있다.
이미 전략전술 통제(C4I), 재무(finance), 의료(healthcare), 제조(manufacturing), 우주항공(space), 통신(telecommunications), 운송(transportation) 등의 도메인을 필두로 그 표준화 작업을 진행 중에 있으며, 여러 표준화 단체들과 연합하여 다른 도메인으로까지 표준화 작업을 확장 중에 있다.
물론 아직까지 그 시도는 기술적인 관점에서의 접근이라는 한계를 크게 뛰어 넘고 있지는 못하지만 인터넷, 즉 IT 기술을 배제한 고전적 의미의 비즈니스는 점차 그 경쟁력을 잃어 가고 있는 현실을 생각할 때 OMG의 영향력은 쉽게 무시할 수 없는 것이 될 것이다.
원칙 둘, 모델의 추상 수준
사전적 의미로도 알 수 있듯이 모델은 본질적으로 어떤 특정 사물이나 현상에 비해 상대적으로 추상화되어 있는 무엇이기 때문에 똑같은 실체에 대한 서로 다른 모델은 서로 다른 추상화 수준(level of abstraction)을 가질 수밖에 없다.
![]() |
<그림 5> 모델의 서로 다른 추상화 수준 |
<그림 5>를 보면 똑같은 자동차를 모델로 만든 것이지만, 상단의 자동차 그림(혹은 모델)은 추상화 수준이 높고 하단의 자동차는 추상화 수준이 낮다. 여기서 중요한 것은 추상화 수준의 높고 낮음은 상대적이라는 것이다. 우리가 UML에서 제시하는 여러 다이어그램을 가지고 모델을 제작한다는 것은 결국 목표하는 자동차나 건물 등과 마찬가지의 실체 즉, 특정 시스템 하나를 완성하기 위한 노력인 것이다.
즉, 설계 작업을 수행한다는 UML 1.4의 표기법을 동원하든 UML 2.0의 표기법을 동원하든 아니면 제3의 표기법을 활용하든 목표하는 시스템을 완성하기 위한 과정이지 다이어그램 혹은 표기법 자체가 목적이 되지는 않는다는 것이다. 이러한 똑같은 모델의 원리를 UML의 다이어그램을 가지고 설명할 수 있다. <그림 5>는 UML 1.4에서 제시하는 9개의 표준 다이어그램의 추상화 수준을 계량화하는 방안으로 방사형의 표로 도식해 본 것이다.
![]() |
<그림 6> UML 1.4 다이어그램 추상화 분포 |
<그림 6>의 중앙에 위치한 지점을 설계자가 목적하는 목표 시스템의 코드 혹은 운영(run-time) 시스템이라고 한다면, 유스케이스 축에서 0.8으로 표시된 지점 정도의 추상화 수준으로 유스케이스를 작성한 것을 비즈니스 유스케이스라 할 수 있겠고, 0.4 정도의 지점 추상화 수준으로 작성한 것을 시스템 유스케이스라고 할 수 있을 것이다. 그렇게 가정해 본다면, 중앙에 가까운 지점의 추상화 수준으로 낮게 모델을 작성한다면 설계자가 목적하는 시스템은 보다 세세하게(detailed) 보이게 될 것이다.
유럽의 모든 길이 로마로 향하듯이, 어떠한 길(다이어그램)을 선택하더라도 종국에는 목적지(목표 시스템)에 도달할 수 있다. 하지만 각 다이어그램은 각자 목표하는 시스템으로 접근할 수 있는 추상화 수준의 한계를 가지고 있다.
가령, 유스케이스 다이어그램만을 가지고 시스템 설계를 완성할 수는 없는 것이다. 반면에, 클래스 다이어그램만 가지고 시스템 설계에 접근하다 보면 나무는 보고 숲을 보지 못하는 우를 범할 수 있다. 그러한 이유로 소프트웨어 설계에서 UML을 활용하여 목표 시스템을 설계할 때는 하나 이상의 다이어그램을 활용하게 된다.
대표적으로 많이 활용되는 다이어그램으로는 유스케이스, 클래스, 시퀀스 등을 들 수 있을 것이다. 문제는 여기서부터 시작 된다. 시스템 설계에 대표적인 3개의 다이어그램을 활용하든 아니면 9개의 다이어그램을 모두 활용하든 활용하는 다이어그램들이 각자 따로 존재하게 되는 것이다.
유스케이스 다이어그램 따로 클래스 다이어그램 따로 심지어는 동일한 시스템에 대한 유스케이스 다이어그램을 그리더라도 그리는 사람에 따라 서로 다른 추상화 수준(level of abstraction) 혹은 입도(granularity)의 유스케이스가 작성된다는 것이다. 이건 비즈니스 유스케이스니 이건 시스템 유스케이스니 하면서 무의미한 논쟁으로 치닫게 된다.
이러한 문제를 본질적으로 해결책하기 위해서는 그것이 UML 1.4이든 UML 2.0이든 각 다이어그램의 주된 용도(usage)와 목적(objectives), 그리고 그 한계를 충분히 이해하고, 각 다이어그램이 그러한 용도와 목적을 충족시키기 위해 제시하는 특성 표기법의 명확한 의미와 용도를 숙지해야 한다. 그 후에 활용하려는 다이어그램의 핵심 표기들 간의 추상화 수준에 대해 일관된 원칙(principle)을 우선 정립하고 설계 작업을 수행해야 한다.
가령 이러한 원칙 수립이 가능하다. 유스케이스 다이어그램을 통해 작성한 하나의 유스케이스를 하나의 활동도(Activity Diagram)로 도식하기로 했다면, 활동도의 활동(Activity)은 유스케이스 시나리오로 작성하는 사건 흐름(flow of event) 상의 단일 스텝(step)이라는 원칙을 설정하게 되면 일관된 설계 작업을 수행할 수 있다. 그러한 설계 전략을 위 <그림 6> 위에 상징적으로 표현해 보면, <그림 7>과 같이 도식할 수 있을 것이다.
![]() |
<그림 7> 다이어그램 간의 추상화 수준 조정 |
지금까지 UML 1.4를 중심으로 모델의 추상 수준이라는 원리에 대해 살펴보았다. 그러한 모델의 추상 수준이라는 핵심 메커니즘은 본질적으로 UML 2.0이라고 해서 다르지 않다. 앞선 <그림 1>과 <그림 7>을 언뜻 비교해 보아도 UML 2.0에서는 표준 다이어그램의 개수로도 UML 1.4에 비해 수적으로 많이 늘어났으며(<그림 4>에서 빨간색으로 표시된 다이어그램), 이전부터 있었던 몇몇 다이어그램들은 명칭이 변경됐고(<그림 4>에서 초록색으로 표시된 다이어그램), 무엇보다도 전반적으로 모든 다이어그램들이 보다 섬세한 설계자의 의도를 반영할 수 있도록 세부적인 표기들이 많이 추가되고 세분화됐다. 즉, 사용할 수 있는 다이어그램 선택의 폭(width)이 넓어졌고, 설계자의 의도를 보다 정밀하게 반영할 수 있는 깊이(depth)도 깊어졌다.
원칙 셋, 모델 자체의 완성도를 높이자
앞서 소프트웨어 업계에서 최근 발생하고 있는 현상들을 통해 잠시 언급했지만, UML 관련 국내외 포럼이나 협회들을 중심으로 UML 자체 혹은 설계 능력 인증 제도가 점차 많아지고 있다. 필자가 인증 제도의 본질적인 목적이나 그 가치 자체를 부정하는 것은 아니지만, 올해 사회적으로 충격을 던져 주었던 대입 수능 시험에서의 대량 부정 사태라든지, 얼마 전부터 공공연하게 제기됐던 영어 관련 인증 제도 등에서 발생하고 있는 문제점 등에 비추어 UML 인증 제도에서도 충분히 발생할 수 있는 그 변별력 문제에 대해 우려를 감출 수 없다.
그러나 다행히도 UML 2.0이 가지고 있는 그 강력한 표현력(semantic expressiveness)과 섬세함(elements precision) 그리고 다이어그램들간의 유기적 연결성 지원(support for diagram interchange) 능력으로 인해 인증서를 가지고 있다고 들먹이지 않아도 모델 결과물 자체로 그 완성도를 검증(self verification)할 수 있다. 즉, 모델 결과물만으로도 충분히 설계자의모델링 역량을 충분히 증명할 수 있는기반을 제공하고 있는 것이다.
UML 2.0이 공식으로 발표되기 이전 특정 케이스 도구들을 중심으로 시도됐지만 UML 1.4의 제약으로 그 실효성(efficiency)을 의심받았던 코드 자동 생성(automatic code generation) 기능은 케이스 도구들이UML 2.0 엔진으로 교체함으로써 그 완성도를 높일 수 있게 됐다. 더 나아가 UML 2.0이 내포한 그 풍부한 표현력과 정교함은, 특정 플랫폼에 종속적인 코드를 생성해 내기 이전에 케이스 도구의 도움을 통해 모델들만을 가지고 사전에 시뮬레이션마저도 어려운 문제가 되지 않는다.
앞으로의 전망
지금까지 개발자들은 새로운 기술이나 제품이 출시되면, 여기저기서 화려한 수식어와 찬사로 밝은 미래를 전망하는 이야기에 너무나도 익숙해져 있다. 1997년 UML 1.1이 처음 세상에 나왔을 때도 마찬가지였다. 그런 맥락에서 단순히 UML 2.0이라는 새로운 패러다임에 무조건 주목하자고 주장하고 싶지는 않다. 실리에 밝은 국내외 소프트웨어 업체들과 협회들의 행보와 여러 가지 상황을 종합해 보아도 UML 2.0이 소프트웨어 산업계에 미칠 파장의 크기는 실로 엄청날 것으로 예상된다.
그것이 더 이상 거스를 수 없는 현실이라면 그러한 도전에 수동적으로 대처할 것인가, 아니면 능동적으로 대처할 것인가의 문제는 독자 스스로 선택할 문제이다. 혹시 이솝 우화에 나오는 거짓말하는 늑대 이야기에서처럼 중요하다는 말을 너무 자주 들어 개발자들이 UML의 중요성을 공허한 메아리 정도로만 치부하고 지나칠까 걱정될 뿐이다.@
* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다.
'IT 자료 > 소프트웨어 공학' 카테고리의 다른 글
[UML 제대로 알기] ③ 개발 프로세스에 따른 UML 실전 모델링 (0) | 2007.09.27 |
---|---|
[UML 제대로 알기] ② 초보자를 위해 다각도로 살펴본 UML (0) | 2007.09.27 |
[UML 2.0] Unified Modeling Language version 2.0 (0) | 2007.09.27 |
[UML 2.0] OMG의 새로운 표준 UML 2.0 (0) | 2007.09.27 |
[안영회의 UML 강좌21] - Summary (0) | 2007.09.27 |