Class Model

클래스는 데이터 묶음이 아니라 불변식의 울타리다

객체 지향 코드는 멤버를 숨기는 데서 끝나지 않는다. 생성 이후 항상 참이어야 하는 조건을 public API가 지켜 주는지가 핵심이다.

01

상태 정의

필요한 멤버와 파생 가능한 값을 나누고, 저장해야 할 값만 객체 안에 둔다.

02

생성 경로를 제한한다

생성자가 불변식을 만족시키지 못하면 객체를 만들지 못하게 한다.

반쯤 유효한 객체는 버그를 뒤로 미룬다.
03

행동으로 변경한다

외부가 멤버를 직접 조합하지 않고 의미 있는 메서드를 통해 상태를 바꾸게 만든다.

public
의미 있는 명령 객체 사용자가 호출해도 되는 동작과 조회만 둔다.
getter 남발은 사실상 public 멤버일 수 있다.
private
변경 가능한 세부 자료구조 선택, 캐시, 보조 값은 구현 내부로 감춘다.
테스트가 private 구조에 의존하면 리팩터링이 막힌다.
생성자
유효 상태 보장 필수 값 누락, 범위 오류, 중복 리소스를 생성 단계에서 거른다.
초기화 리스트가 대입보다 먼저다.
복사
값 의미 확인 복사한 객체가 독립적인 값인지, 공유 소유인지 명확해야 한다.
포인터 멤버가 있으면 바로 의심한다.

불변식 · 표현 은닉 · 복사 정책 점검

불변식 모든 public 함수가 호출 전후로 객체 조건을 깨지 않는지 말할 수 있어야 한다.
표현 은닉 컨테이너 종류나 정렬 방식이 외부 코드에 새어 나가지 않는지 본다.
복사 정책 기본 복사가 올바른지, 삭제하거나 move 전용으로 만들어야 하는지 결정한다.

객체 조건

class Score {
public:
    explicit Score(int value) : value_(value) {
        if (value < 0 || value > 100) throw std::out_of_range("score");
    }
    int value() const { return value_; }
private:
    int value_;
};