본문 바로가기

Book

동적인 협력, 정적인 코드

이번에도 오브젝트 부록을 정리했는데 마지막 부록이다.

이 책에서 계속 강조하는 협력에 대해서 종합적으로 정리한다.  책 전반적인 부분을 요약하는 내용이 있어서 복습도 되고 좋았다.

 

동적인 협력, 정적인 코드

객체는 동적임. 프로그램은 정적임. 객체는 시간에 따라 다른 객체와 협력하며 계속 변화함. 프로그램은 고정된 텍스트라는 형식 안에 갇혀 있으면서도 객체의 모든 변화 가능성을 담아야 함.
객체지향 프로그램을 위한 2가지 모델이 있음 하나는 실행 구조를 표현하는 동적모델, 다른 하나는 코드의 구조를 담는 정적 모델임.
동적 모델은 객체와 협력, 정적 모델은 타입과 관계로 구성됨.
책에서도 전반적으로 이야기했지만, 대부분의 사람들은 정적 모델을 중심으로 설계를 해나간다고 함. 하지만 동적모델이 더 중요하고 그걸 토대로 설계를 진행해야 함.
동적 모델을 기반으로 정적 모델을 구상할 때 고려해야 하는 중요한 요소는 변경임. 설계가 필요한 이유는 변경을 수용할 수 있는 코드를 만들기 위해서임. 즉 결합도가 낮고 단순하고 중복 코드가 없는 거임.
이를 위해서는 협력에 초점을 맞춰야 한다.

01. 동적 모델과 정적 모델

행동이 코드를 결정한다

이건 13장에서 언급한 단순한 is-a 관계가 아닌 행동호환성을 기반으로 설계하는 예시를 다시 한번 정리함.
정적 모델을 설계하는 이유는 단지 행동과 변경을 적절하게 수용할 수 있는 코드 구조를 찾는 것이어야 한다고 함. 중요한 건 객체 외부에 제공하는 행동.

변경을 고려하라

여기서는 단순히 행동 측면으로 적절히 고려해서 설계해도 변경이 힘들면 좋은 설계라 볼 수 없음. 그래서 단순 상속이 아닌. 합성과 제대로 된 서브타입을 기반으로 설계했던 핸드폰 요금 정책 예시를 다시 한번 정리함. 상속 코드는 정책 추가 시 중복 코드가 기하급수적으로 증가하고, 유연하지 않고, 변경하려면 데이터 상태 복사가 필요함.

그렇다면 한 가지 의문점을 이야기하는데, 보통 객체 지향 이야기 할 때 도메인 모델이라는 개념을 소개하면서 이걸 먼저 만들고 그걸 기반으로 설계를 진행하라고 함. 그렇다면 지금까지 이야기한 것과 반대되는 것이 아닌가?라고 생각 할 수 있음. 이 이야기를 이어서 2절에서 함

02. 도메인 모델과 구현

도메인 모델에 관하여

도메인이란 사용자가 프로그램을 사용하는 대상 영역을 가리킴. 모델이란 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태임. 도메인 모델이란

사용자가 프로그램을 사용하는 대상 영역에 대한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태임.


객체지향 분석 설계에서 제안하는 지침 중 하나는 도메인에 대해 고민하고 모델을 기반으로 소프트웨어를 구축하는 것이다. 여기서 중요한 것은 모데인 모델이 목표가 아니라 출발점임. 궁극적인 목적은 동작하는 소프트웨어를 만드는 것임.

모델은 옳거나 틀린것이 아니다. 모델은 유용하거나 유용하지 않은 정도의 차이만 있을 뿐이다[Fowler96]

도메인 안의 개념이 제공하는 틀에 맞춰서 소프트웨어를 경직되게 구축해야 한다는 생각이 잘못된 코드 구조를 낳는 원인이 됨. 그리고 도메인 모델 자체도 정적인 다이어그램이라던지 특정한 형태로 표현되어야 한다는 것 역시 오해다.

도메인 모델은 코드의 구조에 대한 힌트를 제공할 수 있다면 어떤 형태로 표현하더라도 상관이 없다. 객체 사이의 협력을 도드라지게 보여주는 개념적인 표현 역시 도메인 모델이 될 수 있음


중요한 것은 소프트웨어의 기능과 객체의 책임임. 도메인 안의 개념이 아니라 객체들의 협력이 코드의 구조를 이끄는 거임. 시작은 도메인 모델로 해서 맞지 않으면 그걸 수정해 나가야 하는 거임.
코드를 주도하는 건 행동이 되어야 함. 변경이라는 요소가 들어가면 문제는 더 복잡해짐. 도메인 모델에 집착하는 설계는 변경이 어려운 소프트웨어가 만들어질 확률이 높음

의사 소통 패턴은 객체들이 다른 객체와 상호작용 하는 방법을 관장하는 각종 규칙으로 구성되어 있음 . ... 도메인 모델은 의사소통 패턴에 속함. 의사소통 패턴은 객체 간에 있을 법한 관계에 의미를 부여하기 때문임.... 도메인 모델은 명확하게 드러나지 않는데, 이는 의사소통 패턴이 우리가 사용하는 프로그래밍 언어로 명확하게 표현되지 않기 때문임. ... 정적인 분류와 동적인 의사소통 간의 불일치 탓에 ... 객체에 대한 깔끔한 클래스 계층 구조를 생각해 내기란 어려움. 기껏해야 클래스 계층 구조는 1차원적인 애플리케이션을 나타내면서 객체 간의 구현 세부 사항을 공유하는 메커니즘만을 제공함[Freeman09]

몬스터 설계하기

여기서 나이스트롬의 책에서 나오는 예제를 기반으로 설명을 함. 게임 만들 때 몬스터 클래스를 작성하고 그걸 상속받아 자식 클래스들을 만듦, 근데 이렇게 되면 다른 몬스터가 추가될 때마다 , 클래스를 작성해야 함. 물론 이 구조가 개방-폐쇄 원칙을 지키기 때문에 나쁜 설게는 아님. 다만 여기선 목적이 과도한 클래스 추가를 안 하기 위해서 다른 방식을 제안함 그게 그러한 몬스터들을 묶는 타입 같은 class를 추가함 여기서는(breed를 추가) , 이걸 Monster 클래스의 내부에 인스턴스로 합성시키는 거임.
이것은 새로운 클래스를 추가해야 하는 작업을 인스턴스 생성으로 대체한 것과 동일함. 이게 어떻게 보면 타입을 구현할 수 있는 또 다른 방법임.

이처럼 어떤 인스턴스가 다른 인스턴스의 타입을 표현하는 방법을 TYPE OBJECT 패턴이라 부름

행동과 변경을 고려한 도메인 모델

도메인을 먼저 만들고 그거에 기반해 협력에 필요한 객체의 후보를 도출하고 구현 클래스의 이름과 관계를 설계함. 초기 도메인은 작업을 시작하기 위한 아이디어 덩어리이지 그걸 그대로 카피해서 구현하면 안 됨. 시간이 지날수록 더 변경하기 쉬운 구조와 모델이 떠오른다면 계속 반영해서 수정해야 함.
예를 들어 몬스터 종류를 JSON으로 서술한 것도 일종의 도메인 모델로 볼 수 있음. 오히려 더 이해하기 편함.
도메인 모델은 단순히 클래스 다이어그램이 아님. 도메인의 핵심을 간략하게 단순화해서 표현할 수 있는 모든 것이 도메인 모델임. 형식은 중요하지 않음 전달하려는 의미가 중요함. 코드 구조와 행동을 명확히 드러낸다면 그게 좋은 도메인 모델임.
JSON을 기반으로 하면 , 간단한 역직렬화기를 구현하면 저 데이터를 실제 애플리케이션에서 사용 가능함.
또한 이전에 핸드폰 요금제 예시에서 단순히 관계를 표현한 도표도 동적 모델을 잘 표현하기 때문에 좋은 예시임.
여기서 말하고자 하는 요점은

도메인 모델이 단순히 정적 모델의 형태를 띨 필요가 없으며 도메인 모델의 구조가 코드와 다를 필요가 없다는 거임

. 도메인 모델은 코드를 위한 것임. 도메인 모델은 도메인 안에 존재하는 개념과 관계를 표현해야 하지만 최종 모습은 객체의 행동과 변경에 기반해야 하고 코드의 구조를 반영해야 함.

중요한 건 도메인 모델을 봤을 때 도메인의 개념뿐만 아니라 코드도 함께 이해될 수 있는 구조를 찾는 거임

분석 모델, 설계 모델 그리고 구현 모델

분석 모델은 해결 방법에 대한 언급 없이 도메인에 초점을 맞춘 모델임. 이를 바탕으로 기술적인 관점에서 설루션을 서술하는 설계 모델이 만들어짐. 프로그래머는 이렇게 만들어진 청사진을 기반으로 구현 모델을 만든다.
그러나 여기서 말하고 싶은 점은 이 3개가 명확이 구분되기가 힘들다는 거임. 오히려 구분되면 소프트웨어에 악영향을 미친다고 함. 반대로 분석, 설계, 구현이 동일한 모델을 유지하는 게 이상적이라고 함.
마틴파울러도 경계가 뚜렷한 거보다 이론적으로는 분석인 동시에 설계적 특성을 갖는 모델이 좋다고 함.
프로그래밍 작업을 하면서 기존 설계 모델이 적용 기술 내에서 구현 불가능해 보이면 설계 모델을 수정하고 그 실현 가능성과 정확성은 계속 검증되고 테스트되어야 함.
모델링 툴에 저장된 다이어그램이 코드와 상관이 없다면 당장 그 다이어그램을 파기하고 모델링 툴을 쓰지 않는 게 맞음. 또한 분석 모델을 설계 모델로 변환하는데 시간이 많이 든다면 설계 모델을 도메인을 반영하도록 바꾸고 분석 모델은 그냥 제거하는 게 나음.

그니까 맹목적으로 만들고 유지할 필요가 없다는 거임
객체지향 프로그래밍은 이렇게 도메인을 표현하는 방법과 프로그램 코드 표현 방법이 동일하다는 장점이 있음. 분석, 설계, 구현 모델이 다르다는 생각을 버리고 별개의 활동이라는 생각을 버려야 함.

객체지향 언어는 도메인을 바라보는 관점을 소프트웨어에 투영할 수 있는 다양한 기법을 제공함.

설계 혹은 설계의 주된 부분이 도메인 모델과 대응하지 않는다면 그 모델은 그다지 가치가 없으며 소프트웨어의 정확성도 의심스러워짐. ... 모델이 구현에 대해 비현실적으로 보이면 새로운 모델을 찾아내야 함. 모델이 도메인의 핵심 개념을 표현하지 못해도 새로운 모델을 찾아내야 함. 그래야만 모델링과 설계 프로세스가 하나의 반복 고리를 형성할 수 있음[Evans03].

정리하자면 다음과 같음.

프로그램 코드는 도메인의 개념적인 분류 체계가 아니라 객체의 행동과 변경에 영향을 받음.

그리고 객체지향 패러다임에 대한 흔한 오해와는 다르게 분석 모델과 설계 모델, 구현 모델 사이에 어떤 차이점도 존재하지 않음. 이들 모두 행동과 변경이라는 요소에 영향을 받으며 전체 개발 주기 동안 동일한 모양을 지녀야 함.
객체지향 패러다임의 강점은 전체 개발 주기에 걸쳐 동일한 기법과 표현력을 유지할 수 있다는 점임. 세부적인 내용은 각 모델별로 다를 수 있지만 설계의 초점은 동일함. 행동과 변경임.

 

참고 및 출처: <오브젝트> (조영호 지음, 위키북스 , 2019)

'Book' 카테고리의 다른 글

계약에 의한 설계  (0) 2024.02.04
부분적 경계  (1) 2024.02.02
정책과 수준 그리고 업무 규칙  (0) 2024.01.19
컴포넌트 응집도, 결합  (1) 2023.12.31
프로그래밍 패러다임  (0) 2023.12.22