ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 13. 모델링 : 클래스 설계의 토대
    Study/내 코드가 그렇게 이상한가요? 2024. 2. 26. 06:18
    반응형

    동작 원리와 구조를 간단하게 설명하기 위해, 사물의 특징과 관계를 그림으로 나타낸 것을 모델, 모델을 만드는 것을 모델링이라고 한다.

    1. 악마를 불러들이기 쉬운 User 클래스

    로그인 사용자를 나타내는 User 클래스는 웹 서비스에서 자주 볼 수 있다. 이러한 User 클래스는 사양 변경이 굉장히 잦아서 여러 문제를 일으키기 쉽다.

    class User {
        int id;
        String name;
        String email;
        String passwordDigest;
        String address;
        String phoneNumber;
        String bio;
        String url;
        int discountPoint;
        String themeMode;
        LocalDate birthday;
        String corporationNumber;	// 법인 등록번호
        // ...
    }

    위 User 코드는 구매자와 더불어 법인 사용자에서도 사용하기 위해 corporationNumber라는 필드를 추가했다. 이 코드는 법인 사용자를 관리하는 CorporationManager에서 등록한 User를 일반 사용자를 관리하는 UserManager에서 오류가 발생하는 등(일반 등록번호 존재X) 문제가 발생할 여지가 있다.

    2. 모델링으로 접근해야 하는 구조

    2.1 시스템이란?

    사전적 정의는 '수많은 구성 요소로 이루어진 집합체로서, 각가의 부분이 유기적으로 연결되어, 전체적으로 하나의 목적을 갖고 움직이는 것'이다. 예를 들어, 목적지로 이동하기 위해서, 사람은 두 다리를 번갈아 움직이면서 이동하는 '이족 보행 시스템'을 사용할 수도 있고, 자동차와 비행기 등 다른 시스템을 활용할 수도 있다. 여기서 자동차와 비행기 등의 시스템이 만들어진 이유는, 이 시스템을 활용하여 목적 달성을 더 효율적으로 하기 위해서(더 빨리 이동하기 위해서)이다. 시스템은 목적 달성을 위한 수단이다. 즉, 기술의 본질은 능력을 확장하는 것이라고 할 수 있다.

    2.2. 시스템 구조와 모델링

    시스템 구조를 설명하기 위해 단순한 상자로 도식화한 것이 모델이며, 모델의 의도를 정의하고 구조를 설계하는 것이 모델링이다. 즉, 모델은 목적을 달성하기 위한 수단의 일부를 개념화한 것이다.

    모델이란 특정 목적 달성을 위해 최소한으로 필요한 요서를 갖춘 것이다.

    2.3 소프트웨어 설계와 모델링

    모델이란 특정 목적을 달성하기 위해서, 최소한으로 필요한 요소를 갖춘것 이라고 했으므로, 설계 시 최소한으로 필요한 요소들만 포함하여야 한다. 너무 많은 정보를 포함하면 모델의 목적을 알기 힘들어진다.

    3. 안 좋은 모델의 문제점과 해결 방법

    처음에 작성했던 User클래스는 개인 프로필과 관련된 요소인 생년월일 등과 법인 정보 검증과 관련된 요소인 법인 등록번호 등이 혼재되어 있다. 또한, 로그인 인증과 관련된 이메일 주소와 비밀번호도 포함되어 있는 일관성 없는 모델이다. 모델링을 잘하려면, 반드시 대상이 되는 사회적 활동과 목적을 이해해야 한다.

    목적별로 모델링하기

    사용자를 표현하는 수단은 목적에 따라 이름과 형태가 달라진다. 사용자와 관련된 목적을 고려한 모델을 생각해보자. 목적 기반으로 이름을 설계하면 아래와 같이 수정할 수 있다.

    • PersonalAccount : 개별 로그인 인증
    • CorporateAccount : 법인 로그인 인증
    • Profile : 특징 표현

    모델을 단순한 '대상'으로 해석하면, 여기에 모든 목적이 담기게 되어 데이터가 거대해지고 일관성 없는 구조가 된다. 모델은 시스템 전체가 아니라 특정한 목적 달성과 관련된 부분만을 추려 표현한 시스템의 일부이다. 목적 달성 수단으로 해석해야 제대로 모델링할 수가 있다. 따라서 10장에서 살펴보았던 '목적 중심 이름 설계'를 잘 수행한다면, 목적을 달성하기에 적절한 모델을 설계할 수 있다.

    또한 8장에서 설명한 '단일 책임 원칙'과도 이어진다. 목적과 책임은 서로 대응 되는 관계이므로, 단일 책임 원칙은 단일 목적 원칙이라고 바꿔 말할 수 있다. '클래스가 이루어야 하는 목적은 반드시 하나여야 한다'라는 것이다. 특정 목적에 특화되게 설계해야, 변경하기 쉬운 고품질 구조를 갖게 된다.

    모델을 다시 확인하는 방법

    모델이 잘못되어 있거나, 보자연스럽거나, 일관성이 없는 경우에는 다음을 검토해보자.

    • 해당 모델이 달성하려는 목적을 모두 찾아낸다.
    • 목적별로 모델링을 다시 수정한다.
    • 목적 중심 이름 설계를 기반으로 모델에 이름을 붙인다.
    • 모델에 목적 이외의 요소가 들어가 있다면 다시 수정한다.

    모델과 구현은 반드시 서로 피드백하기

    모델은 구졸르 단순화한 것에 불과하므로, 모델을 기반으로 클래스를 설계하면서 세부적인 내용을 수정해야 한다. '모델 = 클래스'는 아니며, 일반적으로 모델 하나는 여러 개의 클래스로 구현된다.

    클래스 설계와 구현에서 무언가를 깨닫는다면, 이를 모델에 피드백하여 모델을 더 정확하게 만든다. 반대로 개선된 모델은 클래스와 코드 품질 향상에 기여한다. '모델의 구조'와 '소스 코드' 사이에 괴리가 생기지 않게 피드백 사이클을 계속 돌리는 것이 설계 품질을 높이는 비결이다.

    4. 기능성을 좌우하는 모델링

    기능성이란 소프트웨어의 품질 특성 중 하나로, '고객의 니즈를 만족하는 정도'를 의미한다.

    숨어 있는 목적 파악하기

    삼품계약을 예로 들어보자.

    매매 계약 목적물
    ID, 계약 체결 일시, 인도 희망일, 지불 기일, 결제 방법 ID, 상품 ID, 대금, 수량

    상품 구매는 법적으로 매매 계약이므로, 지불 시기와 결제 방법 등 지불 조건이 지정된 내용이 시스템에 반영되어야 한다.

    기능성을 혁신하는 '깊은 모델'

    고등어와 꽁치라는 두 모델을 추상화할 때, 특별한 관점이 정해져 있지 않다면 '어류'로 추상화할 수 있을 것이다. 여기에 돼지가 추가되면, '포유류'로 묶고 어류와 포유류를 '동물'로 묶을 수 있다. 하지만, 목적 달성 수단으로서의 모델의 의미를 생각하여 다시 추상화를 해보면, 고등어, 꽁치, 돼지를 '영양 섭취 수단'이라는 하나의 목적으로 묶을 수 있다. 이렇게 되면, 추상화했을 때 모델의 확장성이 커진다.

    같은 목적 달성 수단이라고 해도, 구조에 따라 달성 효율이 다르다. 즉, 구조를 개선하여 기능을 현신할 수 있다. 도메인 주도 설계에서는 이처럼 '본질적 과제를 해결하고, 기능성 혁신에 공헌하는 모델'을 깊은 모델(deep model)이라고 부른다. 깊은 모델은 수많은 시행 착오를 거듭하고, 모델을 계속해서 개량하는 과정에서 발상이 전환되고, 이 과정에서 기존의 한계를 극복할 수 있는 깊은 모델이 만들어진다. 설계는 한 번 했다고 끝나는 것이 아니라, 매일매일 반복해서 개선하는 것이 중요하다.

    반응형
Designed by Tistory.