본문 바로가기
객체지향

객체지향의 사실과 오해(4-2)

by browoo97 2022. 3. 27.

객체지향 설계 기법

역할, 책임, 협력은 견고하고 유연한 객체지향 설계를 낳는다. 이제 이 관점에서 애플리케이션을 설계하는 유용한 세가지 기법을 살펴보도록 하자.

 

  1. 책임-주도 설계
  2. 디자인 패턴
  3. 테스트-주도 개발

 

1. 책임-주도 설계

객체지향 설계의 핵심은 올바른 책임을 올바른 객체에 할당하는 것이다. 그저 객체지향 언어를 사용하거나 UML과 같은 모델링 언어를 이용해 설계의 밑그림을 그린다고 해서 효율적이고 견고한 객체지향 시스템이 보장되는 것은 아니다.

 

현재 가장 널리 받아들여지는 객체지향 설계 방법은 레베카 워프스브록이 고안한 “책임-주도 설계” 방법이다. 말그대로 객체의 책임을 중심으로 시스템을 구축하는 설계 방법을 뜻한다.

 

시스템의 책임을 객체의 책임으로 변환하고, 각 객체가 책임을 수행하는 중에 필요한 정보나 서비스를 제공해줄 협력자를 찾아 해당 협력자에게 책임을 할당하는 순차적인 방식으로 객체들의 협력 공동체를 구축한다.

 

설계 절차

  • 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악한다.
  • 시스템 책임을 더 작은 책임으로 분할한다.
  • 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
  • 객체가 책임을 수행하는 중에 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾는다.
  • 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 한다.

 

2. 디자인 패턴

패턴은 모법이 되는 설계를 의미한다. 책임-주도 설계의 경우 방법과 절차를 제시하는 반면, 패턴은 책임-주도설계의 결과를 표현한다. 즉 반복적으로 발생하는 문제와 그 문제에 대한 해법을 미리 패턴으로 만들어 개발자들의 설계를 돕는다.

 

디자인 패턴과 관련된 가장 유명한 패턴 책, GOF의 "디자인 패턴"은 23개의 디자인 패턴들을 상세하게 정리해 놓았다.

한 가지의 예로 COMPOSITE 패턴을 살펴보자.

COMPOSITE 패턴은 전체와 부분을 하나의 단위로 추상화하는 경우에 사용할 수 있는 패턴이다.  예를 들어 윈도우 탐색기의 경우 개별적인 파일 단위로 경로를 변경해야할 수 도 있지만 폴더의 경로를 변경함으로써 폴더 안에 포함된 모든 파일의 경로를 한 번에 변경할 수 있다. 이 처럼 클라이언트 입장에서 메시지 수신자가 부분(파일)인지 전체(폴더)인지에 상관 없이 동일한 메세지(경로변경)를 이용해 동일한 방식으로 대상과 상호작용하고 싶을 때 사용할 수 있는 패턴이다.

 

중요한 것은 그림에 표현돼 있는 구성 요소가 클래스와 메서드가 아니라 '협력'에 참여하는 '역할'과 '책임'이라는 사실이다. Component는 클라이언트와 협력할 수 있는 공용 인터페이스를 정의하는 역할을 수행하고 있고 Leaf는 공용 인터페이스에 대한 오퍼레이션 호출에 응답할 수 있는 기본적인 행위를 구현한다. Composite은 외부로부터 부분에 대한 세부 사항을 감추고 포함된 부분을 하나의 단위로 행동하는 역할을 수행한다.

 

Component, Leaf, Composite이 역할이라는 사실은 실제로 구현 시에는 다양한 방식으로 역할을 구현할 수 있다는 사실을 암시한다. 심지어 하나의 객가 세가지 역할을 모두 수행할 수도 있다.

따라서 디자인 패턴은 그저 공통으로 사용할 수 있는 역할, 책임, 협력의 템플릿이며, 책임-주도 설계의 결과물인 동시에 지름길이다.

 

3. 테스트-주도 개발

  • {RED} 단계에서는 실패하는 테스트 코드를 먼저 작성한다.
  • {GREEN} 단계에서는 테스트 코드를 성공시키기 위한 실제 코드를 작성한다.
  • {BLUE} 단계에서는 중복 코드 제거, 일반화 등의 리팩토링을 수행한다.

중요한 것은 실패하는 테스트 코드를 작성할 때까지 실제 코드를 작성하지 않는 것이다. 이를 통해 실제 코드에 대해 기대되는 바를 보다 명확하게 정의 함으로써 불필요한 설계를 피할 수 있고, 정확한 요구 사항에 집중할 수 있다.

 

하지만 테스트-주도 개발은 객체지향에 대한 경험이 적은 초보자들은 개발을 주도하기 위해 어떤 테스트를 어떤 식으로 작성해야 하는지를 결정하는 데 큰 어려움을 느낀다. 이유는 협력 안에서 객체의 역할과 책임이 무엇이고 이것이 클래스와 같은 프로그래밍 언어 장치로 구현되는 방식에 대한 감각이 덜 갖춰져 있기 때문이다. 

 

테스트-주도 개발은 책임-주도 설계의 기본 개념과 나아가 다양한 원칙과 프랙티스, 패턴을 종합적으로 이해 해야 할 뿐만아니라, 좋은 설계에 대한 감각과 경험을 길러야만 적용할 수 있는 설계기법이다. 역할, 책임, 협력에 집중하고 객체지향의 원칙을 적용하려는 깊이 있는 고민과 노력을 통해서만 테스트-주도 개발의 혜택을 누릴 수 있을 것이다.

댓글