✏️, 💡,❓ 해당 이모지는 저의 생각임을 나타냅니다.
길을 물어 직접 알려주는 방법이 '기능적이고 해결 방법 지향적인 접근법'이라면 지도를 이용하는 방법은 '구조적이고 문제 지향적인 접근법'이다. 지도는 길을 찾는 데 필요한 구체적인 기능이 아니라 길을 찾을 수 있는 '구조'를 제공한다. 그리고 지도는 범용적이다. 지도를 제작한 사람들이 지도를 만들 때는 사용할 사람들이 구체적으로 어떤 목적으로 지도를 사용할지 알지 못한다.
지도를 사용하는 사람들의 요구사항은 계속 바뀐다. 마을까지의 길을 찾을 수도 있고 기차역으로 이동하는 길을 찾을 수도 있다. 지도는 이 모든 요구사항을수용할 수 있는데, 지도는 기능에 비해 상대적으로 잘 변하지 않는 안정적인 지형 정보를 기반으로 하고 있기 때문이다.
지도 은유의 핵심은 기능이 아니라 구조를 기반으로 모델을 구축하는 편이 더 범용적이고 이해하기 쉬우며 변경에 안정적이라는 것이다.
사람들의 요구사항은 변하고 모델이 제공해야하는 기능 역시 변할 수밖에 없다. 따라서 기능을 중심으로 구조를 종속시키는 접근법은 범용적이지 않고 재사용이 불가능하며 변경에 취약하다. 사람들에게 직접 길을 묻는 접근법은 기능에 구조를 종속시키는 방법이며 지도는 구조에 기능을 종속시키는 방법이다.
이번 장에서는 기능이 아니라 구조를 바탕으로 시스템을 분할하는 객체지향의 또 다른 측면에 관해 설명한다. 자주 변경되는 기능이 아니라 안정적인 구조를 다라 역할, 책임, 협력을 구성하라.
기능 설계 대 구조 설계
소프트웨어 제품의 설계에는 '기능' 측면의 설계와 '구조' 측면의 설계가 존재한다.
기능 측면은 제품이 사용자를 위해 무엇을 할 수 있는지에 초점을 맞춘다.
구조 측면은 제품의 형태가 어떠해야 하는지에 초점을 맞춘다.
소프트웨어가 가치 있는이유는 사용자가 필요로 하는 기능을 제공하기 때문이다. 이런 관점에서 소프트웨어를 개발하는 일차적인 이유는 사용자에게 훌륭한 기능을 제공하기 위해서다. 소프트웨어 개발 초기에는 사용자가 원하는 것을 만족시키기 위해 시스템이 어떤 기능을 제공하는지에 초점을 맞춰야 한다.
훌륭한 기능이 훌륭한 소프트웨어를 만드는 충분조건이라면, 훌륭한 구조는 훌륭한 소프트웨어를 만들기 위한 필요 조건이다. 성공적 소프트웨어들이 지는 공통적인 특징은 훌륭한 기능을 제공하고 + 새로운 기능을 빠르고 안정적으로 추가할 수 있다는 것이다.
요구사항이 변하지 않는다면 코드를 어떻게 작성하는지를 가지고 골치를 썩을 필요도 없을 것이다.
하지만 불행히도 요구사항은 변경된다. 소프트웨어 분야에서 예외가 없는 유일한 규칙은 요구사항이 항상 변경된다는 것이다. 설계라는 행위를 중요하게 만드는 것은 변경에 대한 필요성이다.
개발자의 삶이 고단하면서 흥미로운 이유는 요구사항이 예측 불가능하게 변경되기 때문이다.
하지만 우리는 미래의 변경을 예측할 수는 없다. 불확실한 미래의 변경을 예측하기 이를 성급하게 설계에 반영하는 것은 불필요하게 복잡한 설계를 낳을 뿐이다.
미래에 대비하는 가장 좋은 방법은 변경을 예측하는 것이 아니라 변경을 수용할 수 있는 선택의여지를 설계에 마련해 놓는 것이다. 설계자는 미래에 구체적으로 어떤 변경이 발생할 것인지를 예측하지 않는다. 단지 언젠가는 변경이 발생할 것이며 아직 그것이 무엇인지 모른다는 사실을 받아들인다. 설계의 일차적인 목표는 변경에 소요되는 비용을 낮추는 것이다.
전통적인 기능 분해는 기능을 중심으로 설계한 후 구조가 기능을 따르게 한다. 이 경우 기능은 더 작은 기능으로 분해되고 각 기능은 서로 밀접하게 관련된 하나의 덩어리를 이루기 때문에 기능이 변경될 경우 소프트웨어가 전체적으로 요동친다.
객체지향 접근방법은 시스템 기능을 객체간 책임으로 분배한다. 시스템 기능은 더 작은 책임으로 분할되고 적절한 객체에게 분배된다.
안정적인 재료: 구조
일반적으로 기능을 수집하고 표현하기 위한 기법을 유스케이스 모델링이라고 하고, 구조를 표현하기 위한기법을 도메인 모델링이라고 한다.
도메인 모델
소프트웨어를 사용하는 사람들은 자신이 관심있는 특정 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.
도메인 모델에서 모델이란 대상을 단순화해서 표현한 것이다.
복잡한 바다에서 길을 잃지 않고 중요한 문제에 집중할 수 있도록 필요한 지식만 재구성한 것이다. 즉, 대상을 추상화하고 단순화한 것이다. 모델을 사용하면 현재의 문제와 관련된 측면은 추상화하고 그 밖의 관련 없는 세부 사항에 대해서는 무시할 수 있다.
소프트웨어의 도메인이 무엇이건상관없이 그곳에는 항상 도메인과 관련된 사람들이 도메인을 바라보는 모델이 존재한다.
도메인 모델은 이해관계자들이 바라보는 멘탈 모델이다. 멘탈 모델이란 사람들이 세상을 이해하기 위해 자신이 상호작용하는 사물들에(자기 자신, 다른 사람, 환경) 대해 갖는 모형이다.
도널드 노먼은 제품을 설계할 때 제품에 관한 모든 것이 사용자들이 제품에 대해 가지고 있는 멘탈 모델과 일치해야 한다고 주장한다. 사용자들은 멘탈 모델과 유사하게 제품이 움직일 거라고 기대하기 때문에 훌륭한 디자인이란 사용자가 예상하는 방식에 따라 정확히 반응하는 제품을 만드는 것이다.
✏️ 사용자가 생각하는 서비스와 설계자가 생각하는 서비스가 일치해야 한다는 것 같다.
도메인 모델은 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지를 포괄하도록 추상화한 소프트웨어 모델이다.
도널드 노먼의 주장을 요약하면 최종 제품은 사용자의 관점을 반영해야 한다. 그리고 최종 코드 역시 사용자가 도메인을 바라보는 관점을 반영해야 한다. 이것은 곧 애플리케이션이 도메인 모델을 기반으로 설계되어야 한다는 것을 의미한다. 도메인 모델 기반으로 설계한다면 도메인을 이해하면 코드를 이해할 수 있게 된다. 도메인 모델이 코드 안에 존재하는 미로를 헤쳐나갈수 있는 지도를 제공하는 것이다.
객체지향 커뮤니티에서는 오래전부터 소프트웨어 기능을 기술하기 위해 유스케이스라는 유용한 기법을 사용해왔다.
사용자의 목표를 달성하기 위해 사용자와 시스템간에 이뤄지는 상호작용의 흐름을 정리한 것을 유스케이스라고 한다.
유스케이스의 가치는 사용자들이 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶을 수 있다는 점이다.
유스케이스명: 중도 해지 이자액을 계산한다
일차 액터: 예금주
주요 성공 시나리오:
1. 예금주가 정기예금 계좌를 선택한다.
2. 시스템은 정기예금 계좌 정보를 보여준다.
3. 예금주가 금일 기준으로 예금을 해지할 경우 지급받을 수 있는 이자계산을 요청한다.
4. 시스템은 중도 해지 시 지급받을 수 있는 이자를 계산한 후 결과를 사용자에게 제공한다.
확장: 3a. 사용자는 해지 일자를 다른 일자로 입력할 수 있다.
위 그림(글)은 유스케이스의 중요한 특성을 잘 보여준다.
1) 유스케이스는 사용자와 시스템 간 상호작용을 보여주는 '텍스트'다.
유스케이스의 핵심은 사용자와 시스템간 상호작용을 이야기 흐름으로 표현하는 것이다. 다이어그램에 노력을 쏟지 말라.
2) 유스케이스는 여러 시나리오들의 집합이다.
시나리오는 유스케이스를 통해 시스템을 사용하는 하나의 특정한 이야기 또는 경로이다. 이자 계산 유스케이스는 두 개의 시나리오를 포함하고 있다. (3, 3a) 예금주는 당일까지의 이자액을 계산하거나 특정 일자까지의 이자액을 계산할 수 있다. 유스케이스는 하나의 시나리오가 아니라 '이자액 계산'이라는 사용자의 목표와 관련된 모든 시나리오의 집합이라는 걸 알 수 있다. 시나리오를 유스케이스 인스턴스라고도 한다.
3) 유스케이스는 단순한 feature 목록과 다르다.
피처는 시스템이 수행해야 하는 기능의 목록을 나열한 것이다. 예제에서 피처는 '시스템은 정기예금 정보를 보여준다'와 '시스템은 당일이나 현재 일자의 이자를 계산한다'이다. 피처의 단점은 두 피처를 서로 연관이 없는 독립적인 기능으로 보이게끔 만든다는 점이다. 두 피처를 '중도해지 이자액을 계산한다'라는 유스케이스로 묶을 수 있다.
4) 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.
위 유스케이스에서는 사용자가 해지 일자를 선택하기 위해 인터페이스를 어떻게 구성해야 하는지에 대한 정보는 포함되있지 않다. 자주 변경되는 사용자 인터페이스 요소는 배제하고 사용자 관점에서 시스템의 행위에 초점을 맞춘다.
5) 유스케이스는내부 설계와 관련된 정보를 포함하지 않는다.
연관된 시스템의 기능을 이야기 형식으로 모으는 게 목적이지 내부 설계를 설명하는 것이 아니다.
과거에는 유스케이스의 명사 -> 클래스 / 동사 -> 메서드로 대응시키는 방법으로 객체지향을 설명했지만 객체지향 설계는 공학적인 규칙과 원칙을 기반으로 한 변환 작업이 아니다.
유스케이스는 설계 기법도, 객체지향 기법도 아니다.
유스케이스가 단지 시스템의 외부 관점만을 표현한다는 점에 주목하라. 유스케이스는 시스템의 내부 구조나 실행 메커니즘에 관한 어떤 정보도 제공하지 않는다.
유스케이스는 객체지향과도 상관 없다. 객체지향 이외의 패러다임에서도 적용 가능하고 객체지향도 유스케이스 외의 방법으로 요구사항을 명시할 수도 있다.
재료 합치기: 기능과 구조의 통합
불안정한 기능을 안정적인 구조 안에 담으면서 변경에 대한 파급 효과를 줄이는 것은 객체지향 설계자가 갖춰야 할 기본적 설계 능력이다.
도메인 모델은 안정적인 구조를 개념화하기 위해, 유스케이스는 불안정한 기능을 서술하기 위해 가장 일반적으로 사용되는 도구다.
시스템은 사용자와 만나는 경계에서 사용자의 목표를 만족시키기 위해 사용자와 협력에 참여하는 커다란 객체다. 사용자에게 시스템이 수행하기로 약속한 기능 = 시스템의 책임으로 볼 수 있다. 사용자 관점에서 시스템은 전송한 메시지에 응답하는 책임을 가진 객체다.
시스템이 수행해야 하는 커다란 규모의 책임은 시스템 안에 살아가는 더 작은 크기의 객체들의 협력을 통해 구현된다.
💡 이전 스터디때 이야기했던 부분. 객체에게 책임을 할당하는 건 누구인가? 객체들은 시스템의 책임을 나눠갖는다.
시스템에 할당된 커다란 책임 -> 작은 규모의 객체들의 책임으로 세분화 된다.
그렇다면 어떻게 객체를 선택할 것인가? 이 시점에서 도메인 모델이 등장한다. 우리는 도메인 모델에 포함된 개념을 은유하는 소프트웨어 객체를 선택해야 한다.
유스케이스는 사용자에게 제공할 기능을 시스템의 책임으로 보게 함으로써 객체간의 안정적인 구조에 책임을 분배할 수 있는 출발점을 제공한다.
객체의 이름은 도메인 모델에 포함된 개념으로부터 차용하고, 책임은 도메인모델에 정의한 개념의 정의에 부합하도록 할당한다. 예를 들어 이자를 계산하는 책임을 가진 객체는 이자율이 될 것이며, 이자는 이자율에 의해 생성될 것이다. 책임 할당의 기본 원칙은 책임을 수행하는데 필요한 정보를 가진 객체에게 그 책임을 할당하는 것이기 때문이다.
도메인 모델을 기반으로 객체 구조를 설계하는 이유 -> 도메인 모델이 안정적이기 때문.
도메인 모델이 안정적인 이유는 도메인 모델이 다음과 같은 특징을 띠기 때문이다.
- 도메인 모델을 구성하는 개념은 비즈니스가 없어지거나 완전 개편되지 않는한 유지된다. (정기예금, 계좌, 이자 등은 금융상품이 없어지거나 개편되지 않는 한 유지)
- 도메인 모델을 구성하는 개념간 관계는 비즈니스 정책이 크게 변경되지 않는 한 안정적으로 유지된다. (계좌와 이자의 관계)
도메인 모델은 문서나 다이어그램이 아닌 멘탈 모델이다. 사람들이 동일한 용어와 동일하나 개념을 이용해 의사소통하고 코드로부터 도메인 모델을 유추할 수 있게 하는 것이 도메인 모델의 진정한 목표다.
'Book' 카테고리의 다른 글
[객체지향의 사실과 오해: 마무리] 07 함께 모으기 / 부록 A (1) | 2024.11.20 |
---|---|
[객체지향의 사실과 오해] 05 책임과 메시지 (4) | 2024.10.23 |
[객체지향의 사실과 오해] 04 역할, 책임, 협력 (2) | 2024.10.10 |
[객체지향의 사실과 오해] 03 타입과 추상화 (1) | 2024.10.01 |
[객체지향의 사실과 오해] 02 이상한 나라의 객체 (0) | 2024.09.24 |