
불변 객체는 왜 중요할까라는 질문은 생각보다 실무적입니다. 처음에는 setter를 막고 값을 못 바꾸게 하는 엄격한 스타일처럼 보이지만, 실제로는 상태를 추론하는 비용을 줄여주는 설계에 더 가깝습니다.
이번 글에서는 불변 객체를 “멋있어 보이는 원칙”이 아니라, 왜 버그를 줄이고 구조를 단순하게 느끼게 하는지 관점으로 설명하겠습니다.
불변 객체를 너무 교리적으로 보면 오히려 부담스럽습니다. 이 글은 “무조건 immutable이 정답”이 아니라, 왜 상태 추론 비용이 줄어드는지 실무 감각 위주로 설명하는 데 초점을 둡니다.
가장 큰 장점은 추론이 쉬워진다는 점이다
가변 객체는 시간이 지나며 상태가 바뀔 수 있습니다. 그래서 코드를 읽을 때 “이 값이 지금도 같나?”를 계속 확인해야 합니다. 반면 불변 객체는 생성 이후 값이 안 바뀌기 때문에, 한 번 이해한 상태를 더 오래 믿을 수 있습니다.
즉 불변 객체의 진짜 장점은 값이 고정된다는 사실보다, 읽는 사람이 머릿속에서 상태 변화를 덜 추적해도 된다는 점입니다.
왜 버그가 줄어들기 쉬울까
- 공유 참조가 있어도 중간에 값이 바뀌지 않는다
- 예상치 못한 setter 호출이 없다
- 함수 호출 전후 상태 비교가 더 단순해진다
특히 여러 곳에서 같은 객체를 들고 다니는 코드일수록 불변성의 장점이 커집니다. 누군가 중간에 값을 바꿨는지 의심할 일이 줄어들기 때문입니다.
불변 객체는 캡슐화와도 연결된다
캡슐화 글에서 말했듯, 중요한 것은 상태를 아무 데서나 못 바꾸게 하는 일입니다. 불변 객체는 그 점을 아주 강하게 밀어붙인 형태로 볼 수 있습니다. 즉 상태 변경 경로를 아예 없애거나 크게 줄여버리는 것입니다.
그래서 불변 객체는 setter를 없애는 취향 문제가 아니라, 상태 보호를 설계 수준에서 더 강하게 가져가는 방식으로 이해하는 편이 좋습니다.
언제는 오히려 과할 수 있을까
물론 불변 객체가 언제나 정답은 아닙니다. 아주 많은 변경이 짧은 시간 안에 반복되고, 새 객체 생성 비용이나 변환 비용이 민감한 구조에서는 tradeoff가 생길 수 있습니다.
- 변경이 매우 잦고 구조가 크다
- 객체를 계속 새로 만드는 비용이 부담된다
- 불변성을 지키기 위한 보일러플레이트가 과도해진다
즉 중요한 것은 무조건 불변이 아니라, 변경 가능한 상태를 줄일수록 얻는 이익이 큰가를 보는 일입니다.
배경 흐름은 캡슐화 글, 빈혈 도메인 모델 글과도 이어집니다.
마무리
불변 객체가 중요한 이유는 상태를 멋있게 잠그기 위해서가 아니라, 상태를 추론하는 비용과 변경 경로를 줄여서 코드를 더 믿기 쉽게 만들기 때문입니다.
즉 불변성은 엄격함을 위한 규칙이라기보다, 복잡한 코드를 덜 복잡하게 느끼게 만드는 설계 도구로 보는 편이 훨씬 실용적입니다.