[객체지향의 사실과 오해] 6장

2020. 4. 28. 09:31책/객체지향의 사실과 오해

6장 객체 지도

유일하게 변하지 않는 것은 모든 것이 변한다는 사실뿐이다. - 헤라클레이토스

 

기능 설계 대 구조 설계

모든 소프트웨어 제품의 설계에는 두 가지 측면이 존재한다. 하나는 '기능'측면의 설계이고, 다른 하나는 '구조'측면의 설계다. 

기능 측면의 설계는 제품이 사용자를 위해 '무엇을 할 수 있는지'에 초점을 맞추고,

구조 측면의 설계는 제품의 형태가 어떠해야 하는지에 초점을 맞춘다.

설계를 하는 목적은 기능과 구조라는 두 가지 측면을 함께 녹여 조화를 이루도록 만드는 것이다.

소프트웨어는 사용자가 원하는 기능을 제공해야한다. 단, 원하는 기능은 가변적이다.

한번만들고 변경될 일 없는 소프트웨어는 거의 존재하지 않는다. 

사용자들의 요구사항은 계속해서 변경되기 때문이다. 이러한 측면에서, 변경되는 요구사항을 충족시키기 쉽고 빠르게 충족시키기 위해서는 그렇게 하기 쉽도록 설계된 구조가 필요하다. 어제 요구받은 기능을 제공하는 동시에 내일 변경될지도 모르는 요구사항도 수용할 수 있는 설계를 창조하는 것은 공학보다는 예술에 가깝다.

이때, 요구사항의 변경에 우리는 어떻게 대처해야할까? 

우리가 할 수 있는 것은 변경을 예측하는 것이 아니라, 변경을 수용할 수 있는 선택의 여지를 설계에 마련해 놓는 것이다.

나중에라도 변경할 수 있는 여지를 남겨 놓는 설계야 말로 좋은 설계라고 할 수 있겠다. 

객체를 설계할때 역시 마찬가지이다. 객체지향은 객체의 구조에 집중하고 기능이 구조를 따르게 만들어야한다.

안정적인 객체 구조는 변경을 수용할 수 있는 유연한 소프트웨어를 만들 수 있는 기반을 제공해 준다. 

객체의 기능을 먼저 고려할 것이 아니라, 객체의 구조를 먼저 고려해야겠다.

 

 

기능과 구조의 통합

불안정한 기능을 안정적인 구조 안에 담음으로써 변경에 대한 파급효과를 최소화하는 것은 훌륭한 객체지향 설계자가 갖춰야 할 기본적인 설계 능력이다. 도메인 모델은 안정적인 구조를 개념화하기 위해, 유스케이스는 불안정한 기능을 서술하기 위해 가장 일반적으로 사용되는 도구다. 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야 한다. 프로그래머는 시스템을 사용자로부터 전송된 메시지를 수행하기 위해 책임을 수행하는 거대한 자율적인 객체로 본다.

시스템은 사용자와 만나는 경계에서 사용자의 목표를 만족시키기 위해 사용자와의 협력에 참여하는 커다란 객체이다.

사용자에게 시스템이 수행하기로 약속한 기능은 결국 시스템의 책임으로 볼 수 있다. 

시스템이라는 객체 안에는 더 작은 규모의 객체가 포함될 수 있는데, 이러한 작은 크기의 객체들이 협력하여 시스템이 수행해야 하는 커다란 규모의 책임을 구현하는 것이다. 정리하자면, 요구사항들을 식별하고 도메인 모델을 생성한 후, 소프트웨어 클래스에 메서드들을 추가하고, 요구사항을 충족시키기 위해 객체들 간의 메시지 전송을 정의한다.

객체의 이름은 도메인 모델에 포함된 개념으로부터 차용하고, 책임은 도메인 모델에 정의한 개념의 정의에 부합하도록 할당한다.

예를들어, 이자를 계산하는 책임을 가진 객체는 이자율이 될 것이며, 이자는 이자율에 의해 생성될 것이다. 이것은 책임할당의 기본원칙이 책임을 수행하는 데 필요한 정보를 가진 객체에게 그 책임을 할당하는 것이기 때문이다. 이자라는 상태값을 가진 객체가 이자라는 상태값을 변경시키는 행위 또한 가지고 있어야 한다는 것이 바로 캡슐화 이기 때문이라는 의미이다.

 

 

기능 변경을 흡수하는 안정적인 구조

앞에서 설명한 것처럼 도메인 모델을 기반으로 객체 구조를 설계하는 것이 안정적인 구조를 설계하는 것이다. 

도메인 모델의 다음과 같은 두가지 특징덕분인데,

  • 도메인 모델을 구성하는 개념은 비즈니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다. 
  • 도메인 모델을 구성하는 개념 간의 관계는 비즈니스 규칙을 기반으로 하기 때문에 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다. 

이와 같은 특징이 의미하는 것은 시스템의 기능이 변경되더라도 객체 간의 관계가 일정하게 유지된다는 것이다.

코딩을 하다보면, 어떠한 변경을 해야할 때 전체적으로 싹 갈아엎어야 할때가 있었다. 그때를 떠올려보면, 객체와 객체간의 관계가 명확하지 않았기 때문이라는 생각이 든다. 도메인 모델을 객체들을 설계한 후 유스케이스의 기능에 따라 객체들에게 책임을 분배하는 것은, 객체간의 관계를 확실하게 정립해준다. 이것은 기능의 변화가 이루어 져야 할때, 그 틀이 무너지지 않는 것을 의미하므로, 유지보수에 용이하다고 할 수 있겠다. 

 

 

느낀점

이번 장은 도메인 모델과 유스케이스에 관한 내용이 주를 이루어 정리한 내용이 조금 짧았다.

도메인 모델과 유스케이스를 설명하기 위해 정기예금 과정을 예시로 사용해주셨는데, 이곳에 적게되면 혼란스러울 것 같았다. 

하지만 도메인 모델과 유스케이스를 기반으로 한 설계와 구현의 중요성은 확실하게 알았다. 

책임-주도 설계를 구체적으로 하는 방법이랄까? 

친숙한 예시인 앨리스 이야기를 통해 짧게나마 요약해 보자면, 

'재판'이라는 시스템이 이루어지기 위해서, 

그 재판이라는 요소들을 이루는 '왕', '토끼', '모자 장수' 라는 객체들이 필요하다. 이것을 도메인 모델링 하여 각 객체들간의 관계를 정립하고 어떠한 객체가 어떠한 책임을 지게 할것인지 분배해 주는 것이다. 

결국엔, 좋은 객체지향 설계를 하는 구체적인 방법에 관한 것을 다룬 6장이었다. 

도메인 모델링과 유스케이스에 관한 내용은 후에 따로 정리를 한번 해봐야 할 것 같다.