[협업]개발 학생의 협업 도전기 #2-1.객체지향 개발 방법론(OOAD) : OOP, UP
모든 일에 있어 가장 중요한 일은 개요(또는 목차)를 잡는 것이라고 생각한다.
개요를 잡고 무언가를 시작하게 되면, 큰 문제에 직면하더라도 그것을 조각내서 단순화하여 생각할 수 있고
개요 간의 관계 또한 선명하게 살필 수 있으며 전체 맥락도 빠르게 파악할 수 있는 등의 여러 가지 장점이 많다고 생각하기 때문이다.
이 개요라는 것은 비단 문장에서뿐만 아니라 어떤 영역에서든 적용될 수 있고, 각 영역에서 정의하는 그들만의 단어로 표현되는 듯하다.
소프트웨어 개발에 있어서 이러한 개요는 '설계'라는 단어로 표현할 수 있지 않을까.
무턱대고 각종 IDE를 실행하여 일단 코드를 써 내려가는 것보다는, 먼저 시스템에 대한 도메인을 파악하고, 아키텍처를 잡고
각 모듈들간의 관계에 대해 파악하는 등의 일련의 '개요 잡기' 행위를 통해 훨씬 더 정교하고 유지보수에 용이한 시스템을 제작할 수 있다.
지난 학기에는 C언어를 대표 주자로 하는 절차 지향 언어의 설계 방법론인 SASD(Structured-Analysis and Design) 강의를 수강하였다.
절차 지향은 Data Flow를 중점으로 하는 사상이어서, SASD에서는 데이터 input과 해당 데이터에 대한 handling 및 output에만 관심이 있다.
그러나 객체지향 사상은 이름에서도 알 수 있듯 '객체'의 구성과 동작을 중심으로 한다.
따라서 특수한 경우가 아니고서는 객체지향 언어는 Data Flow보다 객체들간의 관계에 포커스를 맞춘다.
객체지향 언어는 어떠한 프로세스와 방법론으로 구성되는지 궁금하여 이번 학기에는 '객체지향 개발 방법론(OOAD)' 강의를 수강하였다.
이 수업은 프로젝트형 수업으로 OOPT(Object-oriented process with Traceability)라는, 수업을 진행하는 연구실에서 자체 개발한 프로세스를 따라 진행되었고, 이 부분에 대해 다뤄보려 한다.
OOPT가 흥미로웠던 점은 동일한 교수님의 강의 중 '소프트웨어 검증'이라는 강의가 있는데, 해당 강의를 본 강의와 연동하여 개발팀-검증팀 관계를 구축해 개발팀에서 개발하거나 수정한 시스템을 github을 통해 메인 브랜치에 push하면 검증팀에서 Jenkins와 같은 테스팅 서버를 통해 여러 테스트를 수행하고, 테스트 결과를 다시 개발팀에 전달함으로써 소프트웨어 품질을 높이는 전략을 사용한다는 점이었다.
개인적으로 이전부터 관심이 있던 주제여서 수업에서 이러한 시스템을 배우게 되어 나에게는 희소식이었다. 물론 상상하던 것과는 달랐지만..
이외 OOAD 이론 수업은 Applying UML and patterns 교재를 기반으로 진행되었으므로 포스팅 또한 수업 내용과 해당 교재의 자료들을 활용하여 작성된다.
개발 주제는 디지털 시계의 Middle Ware 역할을 하는 Digital Watch System이다.
INDEX
1. OOP(Object-oriented Programming)?
객체 지향 프로그래밍(이하 OOP) 언어는, 언어 자체적으로 '객체'라는 개념이 구현되어 있고 그것이 중심이 되는 언어로, 대표적인 언어로 Java, C++이 있겠다.
객체라는 녀석은 실세계의 여러 가지 개체, 이를테면 사람, 자동차 등을 소프트웨어 내부에 그것들의 중요한 특성을 사용자의 필요에 맞게 담아내어 모방할 수 있게 한다.
자동차를 나타낼 때 필요한 것은, "자동차의 연비, 잔여 기름, 주행량"등의 자동차 관련 정보와 "달리다, 멈추다"등의 동작 이 있을 것이다.
이러한 정보들이 주어지면, 자동차의 정보와 동작을 일부분 서술할 수 있게 된다.(EX. "자동차의 주행량은 500km, 연비는 17km/L이고 현재 주행 중인 상태이다.")
사용자는 자신이 나타내고 싶은 자동차의 모습을 표현해내기 위해 필요한 정보와 동작들을 입맛에 맞게 선언하면 될 것이다.
따라서 객체는, 객체가 가져야 할 정보를 담을 attribute와, 그 정보들을 조작하는 동작인 Method로 구성되어 있다.
사용자는 어떠한 개체를 소프트웨어로 표현하기 위해 attribute를 선언하고, 선언된 attribute를 Method로 조작하는 흐름을 취한다.
아래는 'Student'를 표현하는 객체이다.
Student 객체는 내부에 이름, 주소, Student ID, 생년월일이라는 데이터를 갖고 있고, 해당 데이터들을 조작하고 제어하는 Method를 갖고 있다.
그림에서 attribute들이 마치 Method의 내부에 갇혀있는 느낌을 주는데, 느껴지는 바와 같이 attribute가 외부로 통하기 위해서는 attribute를 둘러싼 Method를 거쳐야 함을 의미한다(물론 언어 자체적 기능은 아니고, 개발자가 그렇게 하는 것이 일반적이다.).
많은 경우 객체의 attribute들은 객체 외부에서 바로 접근할 수 없도록 선언한다(with 접근 제어자).
접근 제어자를 통해 개발자는 데이터에 대한 접근 권한을 적절하게 설정하고, 객체가 갖고 있는 Method를 통해 객체 데이터들을 원하는 방식으로 가공해 넘겨줄 것은 넘겨주고, 감출 것은 감추며 프로그램을 구성한다.
OOP의 설계, 즉 OOAD 프로세스는 External Actor가 시스템에 요구하는 기능들을 만족하기 위해
시스템이 수행해야 할 기능들을 여러 기능들로 분할하고, 분할된 기능들을 수행할 객체들을 구성하고, 구성된 객체들간의 상호 작용을 통해 시스템 요구사항을 만족시킨다.
예를 들어 게시판 기능을 구현하고자 할 때 필요한 기능이
1) 로그인 기능
2) 게시판 글 CRUD 기능
이라고 한다면, 로그인을 담당하는 객체와 게시판 CRUD를 수행하는 객체를 선언하여 로그인 객체가 유효성 검사를 마치면 게시판 객체에게 필요한 기능(Method)들을 수행하도록 명령하는 방식이다. 구체적으로, 로그인을 성공적으로 마치면 게시판 객체에게 글쓰기를 수행하는 등의 기능을 하게 하는 것이라고 볼 수 있겠다.
이렇게, 임의의 객체가 다른 객체에게 필요한 작업을 수행하도록 명령/통신하는 것을 객체간의 'Message Passing'이라고 부른다. 여기서 '필요한 작업'이란 객체가 가진 Method를 의미한다.
요약하면, OOP는 실세계의 개체들을 소프트웨어로 표현하기 위한 '객체'에 포커스를 맞추는 프로그래밍 패러다임이고, OOAD는 OOP를 통해 시스템 요구사항을 만족시키기 위해 필요한 객체들을 찾아내어 구성하고, 그렇게 구성된 객체들간의 상호 작용인 Message Passing을 통해 객체 지향 프로그램을 설계하는 소프트웨어 설계 프로세스이다.
2. UP(Unified-Process)
OOPT가 UP(Unified Process)를 기반으로 하기 때문에, 설명하지 않을 수 없는 주제이다.
UP는 Agile Process로부터 파생된 소프트웨어 개발 프로세스로써 다음과 같은 몇 가지의 특성을 가진다.
1) Iterative Process(반복 프로세스)
UP는 Agile Process로부터 파생된 Iterative한 프로세스이다.
Agile과 상반되는 Process가 Waterfall process인데, Waterfall process는 소프트웨어 개발 단계가
요구사항 분석 -> 설계 -> 개발 -> 테스팅 -> ...과 같은 순서로 명확하게 분리되어 있다. 어떠한 단계를 지나가면 다시 이전 단계로 돌아갈 수 없다는 것이 가장 큰 특징이다.
그러나 소프트웨어를 개발하다 보면 요구사항의 변경이 불가피한 경우는 생기기 마련이고, Waterfall process에서 이런 경우가 발생하면 유연하게 대처하기 쉽지 않다. 요구사항 명세가 잘 변하지 않는 대규모 시스템에서는 Waterfall Process를 선호하는 것으로 알고 있다.
이에 반해 Agile Process는 Iterative한 개발 Process 모델로써, 위의 Waterfall의 과정을 여러 번의 소규모 Waterfall로 나누어 점진적으로 소프트웨어를 개발한다.
그림에서 알 수 있듯, 요구사항 분석 -> 설계 -> 개발 -> 테스팅 -> 평가 및 피드백 -> 요구사항 분석 및 수정 -> ...과 같이 반복적, 점진적으로 시스템의 크기를 키워나간다.
이러한 방식은 조금 더 빠르게 시스템을 개발하고, 요구사항 변화에 대처하기 유리하다.
그러나 문서화를 지양하고 최대한 '개발 위주'의 작업들을 많이 하는 경향이 있기 때문에, 새로운 인원이 해당 프로젝트에 투입되는 비용이 더 많이 들고, 따라서 일반적으로 유지 보수를 더 중요시하는 대규모 프로젝트에는 적용하기 힘들다는 점이 있다.
Agile Process 자체가 일련의 Activity set은 아니고, 비슷한 형태의 iterative, incremental한 프로세스들을 일괄적으로 나타내는 상위 분류인 Umbrella term이다.
Agile Process는 대표적으로 XP(Extreme Programming), TDD등이 있겠다.
UP는 Agile Process와 같이 Iterative하게 진행되는 Process이다.
2) Risk-driven, Client-driven and Architecture-centric Process
UP는 Risk-driven, Client-driven and Architecture-centric Process이다.
Risk-driven이란, 시스템 개발 진행 중에 생길 수 있는 요구사항 변화에 의해 발생할 수 있는 위험 사항들을 개발 초기에 찾아내어 잡아놓는 방식을 의미한다.
이러한 risk는 보통 클라이언트의 요구사항과 구현된 시스템 기능상의 불일치에 따라 발생할 가능성이 높기 때문에,
개발 초기에 몇 회의 Requirements Workshop을 통해 여러 stakeholder들의 피드백을 반영하여 진행하는 Client-driven한 방식을 취한다. 이때, 작은 모듈들이나 기능들의 변화는 용인할 수 있는 정도이나 이것이 시스템 아키텍처를 변화시켜야 되는 수준이면 굉장한 문제가 생기기 때문에, 아키텍처에 중점을 두고(Architecture-centric) 여러 아키텍처의 후보군 중 요구되는 시스템에 적용하기 적합하고, 앞으로도 변하지 않을 아키텍처를 미리 선택하여 고정한다.
위 그림은 UP의 development cycle이다.
UP의 development cycle은 4개의 phase인 Inception-Elaboration-Construction-Transition으로 구성되는데,
Inception phase에서는 이 시스템을 개발할 때의 비용 문제와, 개발할 수 있는지에 대한 feasibility study를 수행하는 단계이기 때문에 약 1주 정도가 소요되고, 나머지 각 phase의 박스 하나(각 iteration)가 보통 3주의 작업 기간으로 산정된다.
Elaboration phase에서는 3주의 iteration마다 mini waterfall을 거쳐 사용자가 요구한 주기능들을 먼저 구현하고,
iteration이 종료되면 구현된 시스템을 가지고 Requirements Workshop을 개최하여 stakeholder들에게 시스템에 대한 피드백을 받는다.
그렇게 여러 회의 iteration을 거쳐 소프트웨어를 지속적으로 다듬고 나면, 대부분의 개발 중 risk들이 탐색되고 요구사항과 아키텍처가 고정되어 이후 phase인 Construction, Transition phase에서는 변하지 않는다.
UP는 이러한 방식으로 위험 사항들을 줄이며 개발을 진행하고, 개인적 의견으로 Agile과 Waterfall의 장점들을 적절하게 차용하여 섞은 느낌이 들었다.
실제로 UP 기반의 OOAD 프로세스가 필드에서 주로 사용하는 de facto industry standard(사실상 표준)라고 한다.
이외에도 UP가 가진 특징들이 여럿 있겠지만, 이쯤하고 넘겨도 괜찮을 것 같다.
OOAD를 얘기하기 전에, OOP와 UP에 대한 얘기를 해보았다.
다음 포스팅부터는 OOPT의 각 Stage에 대한 포스팅을 진행한다.