Mutable
1. 개요
1. 개요
Mutable은 프로그래밍에서 객체가 생성된 이후에도 그 내부 상태를 변경할 수 있는 성질을 가리킨다. 이는 객체 지향 프로그래밍에서 일반적으로 사용되는 개념으로, 변수의 값이나 객체의 속성을 수정, 추가, 삭제하는 것이 가능하다. 대부분의 객체 지향 언어에서 클래스로 생성된 인스턴스는 기본적으로 mutable한 특성을 지닌다.
이 개념의 반대는 상태가 한 번 생성되면 변경할 수 없는 Immutable이다. Mutable 객체는 프로그램 실행 중 동적으로 변화하는 상태를 표현하고 관리하는 데 핵심적 역할을 한다. 주로 상태 변경이 빈번하게 필요한 자료 구조를 구현할 때 사용되며, 대표적인 예로는 배열, 리스트, 사전 등이 있다.
Mutable의 사용은 객체 지향 프로그래밍의 근간을 이루지만, 함수형 프로그래밍 패러다임에서는 부수 효과를 최소화하기 위해 Immutable 객체의 사용을 선호하는 경향이 있다. 따라서 두 개념은 프로그래밍 언어의 설계 철학과 패러다임에 따라 그 중요성과 활용 방식이 달라진다.
2. 특징
2. 특징
Mutable 객체는 생성된 이후에도 그 내부 상태를 수정할 수 있다는 특징을 가진다. 이는 객체의 속성이나 값을 직접 변경, 추가, 삭제할 수 있음을 의미하며, 객체 지향 프로그래밍에서 일반적인 데이터 모델링 방식이다. 이러한 특성 덕분에 프로그램 실행 중에 동적으로 데이터를 조작하고 상태를 업데이트하는 것이 가능해진다.
주요 특징으로는 상태 변화에 따른 부작용이 발생할 수 있다는 점이 있다. 같은 객체를 참조하는 여러 변수나 함수가 있을 경우, 한 곳에서 객체를 변경하면 다른 모든 참조 지점에서도 변경된 상태가 반영된다. 이는 데이터의 일관성을 유지하기 어렵게 만들 수 있지만, 메모리 효율성을 높이는 장점도 동시에 제공한다. 큰 데이터를 복사하지 않고 참조만으로 조작할 수 있기 때문이다.
또한, 자료 구조에서 배열이나 리스트, 사전과 같은 대표적인 가변 객체들은 요소의 추가, 삭제, 수정이 빈번하게 이루어지는 동적 데이터 처리를 위해 설계되었다. 이는 함수형 프로그래밍 패러다임과는 대조를 이루며, 상태 관리와 데이터 흐름 제어에 있어 서로 다른 접근법을 요구한다.
3. 사용 예시
3. 사용 예시
3.1. 프로그래밍 언어별 구현
3.1. 프로그래밍 언어별 구현
파이썬에서는 리스트, 딕셔너리, 집합 등 대부분의 내장 컬렉션이 기본적으로 가변적이다. 예를 들어, 리스트의 요소는 인덱스를 통해 직접 수정, 추가, 삭제할 수 있다. 반면, 튜플, 문자열, 프로즌셋은 불변 객체로, 내용을 변경하려면 새로운 객체를 생성해야 한다. 사용자 정의 클래스도 일반적으로 가변적이며, 속성을 자유롭게 변경할 수 있다.
자바에서는 배열과 컬렉션 프레임워크의 대부분의 클래스(예: ArrayList, HashMap)가 가변적이다. 그러나 문자열은 불변 클래스로 설계되어 있다. 자바에서 가변 객체를 만들기 위해서는 필드에 대한 세터 메서드를 제공하거나, public 접근 제어자를 사용하는 등의 방법을 사용한다.
자바스크립트에서 기본 객체와 배열은 모두 가변적이다. 객체의 프로퍼티를 동적으로 추가, 수정, 삭제할 수 있으며, 배열의 요소도 마찬가지로 변경 가능하다. 그러나 const 키워드로 선언된 변수는 재할당만 불가능할 뿐, 해당 변수가 참조하는 객체나 배열 자체의 내용 변경은 허용된다.
C++에서는 표준 템플릿 라이브러리의 벡터, 맵과 같은 컨테이너들이 가변적이다. 또한, 클래스의 멤버 변수는 기본적으로 가변적이며, const 멤버 함수를 통해 불변성을 보장하는 부분을 제한할 수 있다. C의 구조체도 포인터를 통해 내용을 변경할 수 있는 전형적인 가변 데이터 구조이다.
언어 | 대표적 가변 데이터 구조 | 대표적 불변 데이터 구조 |
|---|---|---|
파이썬 | 리스트, 딕셔너리, 집합 | 튜플, 문자열, 프로즌셋 |
자바 | ArrayList, HashMap | String, Integer(래퍼 클래스) |
자바스크립트 | 객체, 배열 | 원시 값(숫자, 문자열) |
C++ | vector, map | const로 선언된 객체 |
C | 구조체, 배열 | const로 선언된 변수 |
4. Mutable vs Immutable
4. Mutable vs Immutable
Mutable 객체는 생성된 이후에도 그 내부 상태를 변경할 수 있는 객체이다. 이는 객체 지향 프로그래밍에서 일반적으로 사용되는 방식으로, 프로그램의 상태를 표현하고 조작하는 데 적합하다. 예를 들어, 배열에 새로운 요소를 추가하거나 사전의 값을 갱신하는 행위는 객체 자체를 수정하는 것이므로 Mutable한 동작에 해당한다. 이와 같은 특성은 동적인 데이터 처리를 요구하는 애플리케이션에서 유용하게 활용된다.
반면, Immutable 객체는 일단 생성되면 그 상태를 절대 변경할 수 없는 객체이다. 함수형 프로그래밍의 핵심 개념 중 하나로, 객체에 대한 모든 연산은 새로운 객체를 생성하여 결과를 반환한다. 예를 들어, 문자열을 연결하는 연산은 원본 문자열을 변경하지 않고 완전히 새로운 문자열 객체를 만들어낸다. 이는 프로그램의 예측 가능성을 높이고, 동시성 프로그래밍에서 스레드 안전성을 보장하는 데 큰 장점이 된다.
두 개념의 선택은 설계 목표에 따라 달라진다. Mutable 객체는 메모리 사용이 효율적이고 성능상 유리한 경우가 많으나, 상태 변화를 추적하기 어렵고 부수 효과를 발생시킬 수 있다. Immutable 객체는 상태 변화에 대한 복잡성을 제거하고 참조 투명성을 제공하지만, 작은 변경에도 새로운 객체를 생성해야 하므로 성능과 메모리 측면에서 비용이 발생할 수 있다. 현대 프로그래밍에서는 자료 구조 설계 시 두 패러다임을 혼용하여 상황에 맞게 적절히 선택하는 경향이 있다.
5. 장단점
5. 장단점
Mutable 객체는 생성 이후에도 내부 상태를 변경할 수 있어, 동일한 객체에 대해 값을 갱신하거나 내용을 수정하는 작업이 가능하다. 이는 프로그램에서 변하는 상태를 직접적으로 표현하고 관리해야 할 때 유용하다. 예를 들어, 사용자 프로필 정보를 담은 객체의 나이나 주소를 업데이트하거나, 배열에 새로운 요소를 추가·삭제하는 경우에 적합한 방식이다. 대부분의 객체 지향 프로그래밍 언어에서 기본적으로 제공하는 클래스 인스턴스는 대부분 가변적이다.
Mutable의 주요 장점은 메모리 효율성과 성능에 있다. 데이터를 변경할 때마다 새로운 객체를 생성하지 않고 기존 객체의 내용만 바꾸므로, 불필요한 메모리 할당과 가비지 컬렉션 부하를 줄일 수 있다. 특히 큰 규모의 자료 구조를 다루거나 빈번한 수정이 발생하는 알고리즘에서 이점이 두드러진다. 또한, 객체의 식별자(참조)가 변경되지 않아 상태 추적이 비교적 단순해지는 경우도 있다.
반면, Mutable 객체는 부작용을 초래하기 쉬워 프로그램의 복잡성을 증가시킬 수 있다. 여러 부분에서 동일한 객체를 참조하고 있을 때, 한 곳에서의 수정이 예상치 못한 다른 곳의 동작에 영향을 미칠 수 있다. 이는 디버깅을 어렵게 만들고, 동시성 프로그래밍 환경에서는 경쟁 상태나 데이터 불일치 문제를 유발할 위험이 있다. 이러한 이유로 함수형 프로그래밍 패러다임은 상태 변경을 최소화하고 Immutable 불변 객체의 사용을 권장한다.
따라서 Mutable과 Immutable의 선택은 설계 시 신중히 고려해야 한다. 변경 가능성이 높고 성능이 중요한 코어 데이터 구조에는 Mutable을, 예측 가능성과 안정성이 요구되거나 여러 스레드에서 공유되는 데이터에는 Immutable을 적용하는 것이 일반적인 접근법이다. 많은 현대 프로그래밍 언어와 라이브러리는 두 방식을 모두 지원하며, 상황에 맞게 혼용하여 사용한다.
