노트

변수·컬렉션 캡슐화

Encapsulate Variable

설계#refactoring · 연결된 개념 9개

쉽게 말하면

변수 캡슐화는 사무실 비품을 아무나 꺼내 가지 않고 비품 담당자를 거쳐서만 받게 하는 거예요. 누가 언제 무엇을 바꿨는지 한 곳에서 지켜볼 수 있고, 바꾸기 전에 확인도 할 수 있죠.

비유가 깨지는 곳 담당자가 비품 원본을 그냥 건네주면 밖에서 몰래 바뀔 수 있어요. 그래서 컬렉션은 내부 배열 대신 복제본을 돌려주고, add·remove 같은 변경 메서드를 따로 둬요.

넓은 범위에서 쓰이는 데이터에 직접 접근하지 못하게 하고, 읽고 쓰는 함수를 통해서만 다루게 하는 리팩터링. 데이터를 옮기거나 바꿀 때 고쳐야 할 곳이 접근 함수 한 곳으로 좁아진다.

let defaultOwnerData = { firstName: '마틴', lastName: '파울러' }
export const defaultOwner = () => ({ ...defaultOwnerData }) // 복제본을 준다
export const setDefaultOwner = (arg: typeof defaultOwnerData) => { defaultOwnerData = arg }
  • 전역 데이터(Global Data)·가변 데이터(Mutable Data) 냄새의 첫 처방이다. 누가 언제 값을 바꾸는지 감시할 통로가 생기고, 바꾸기 전 검증도 끼워 넣을 수 있다
  • 레코드 캡슐화(Encapsulate Record): 객체 리터럴을 클래스로 감싸면 저장된 값과 계산된 값을 구분할 필요가 없어지고, 이름을 바꿀 때 옛 이름과 새 이름을 함께 제공할 수 있다
  • 컬렉션 캡슐화(Encapsulate Collection): 게터가 내부 배열을 그대로 내주면 밖에서 몰래 원소를 바꿀 수 있다. 복제본을 돌려주고 add·remove 같은 변경 메서드를 따로 둔다. 불필요한 복제가 예상치 못한 수정을 디버깅하는 것보다 싸다
  • 복제할 때 중첩 객체까지 복사되는지는 얕은 복사와 깊은 복사 참고
  • 바뀌면 안 되는 필드는 세터를 아예 없애 불변으로 만든다. 그 끝에는 값 객체가 있다

React에서 상태를 직접 바꾸지 않고 새 객체로 교체하는 규칙(React 상태 갱신)도 같은 문제의식에서 나온다.

출처: 『리팩터링 2판』 마틴 파울러 (원서 Refactoring, 2nd Edition) · refactoring.com: Encapsulate Variable · refactoring.com: Encapsulate Record · refactoring.com: Encapsulate Collection · Refactoring.Guru: Encapsulate Field

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 매개변수 객체 만들기

    여러 함수에 늘 함께 넘겨지는 값 묶음(데이터 뭉치, Data Clumps)을 하나의 객체로 묶어 넘기는 리팩터링.

  • 특이 케이스와 널 객체

    특정 값(가장 흔하게는 null이나 "미확인" 같은 표시값)을 만날 때마다 같은 처리를 하는 코드가 곳곳에 흩어져 있을 때, 그 경우를 대표하는 객체를 하나 만들어 공통 동작을 담는 패턴. null을 대표하면 널 객체(Null Object)라 부르며, 널 객체는 특이 케이스(Special Case)의 한 예다.

  • 내부 가변성과 메모이제이션

    내부 가변성(Interior Mutability)은 객체나 함수의 참조는 그대로인데 안에 숨은 상태가 바뀌는 성질이다. React의 메모이제이션은 "입력이 다른 참조인가"만 보기 때문에, 참조가 같으면 내용이 바뀌어도 바뀌지 않았다고 판단한다. React 공식 문서는 이를 "겉모습은 같은데 몰래 내용물을 바꾸는 상자"에 비유한다.

  • 커맨드 패턴

    요청이나 작업을 실행 가능한 객체로 포장하는 패턴. 작업을 값처럼 저장·전달·대기열에 넣을 수 있게 되고, 되돌리기 같은 부가 연산을 붙일 수 있다.

  • React Compiler

    React Compiler는 빌드 타임에 컴포넌트와 훅을 분석해 메모이제이션(Memoization) 코드를 자동으로 넣어 주는 컴파일러다. 개발자가 손으로 붙이던 useMemo·useCallback·memo를 대신한다. 2025년 10월 1.0이 나왔다.

보기 옵션