State, Mutable State 및 Immutable State는 무엇입니까?


32

이것은 초보자 질문이지만 Google에서 초보자에 대한 충분한 답변을 찾을 수 없습니다.

사람들이 '상태'라고 말할 때 일반적으로 프로그래밍, 구체적으로 OO 프로그래밍에서 무엇을 의미합니까?

또한 일반적으로 프로그래밍 및 특히 OOP에서 변경 가능하고 변경 불가능한 상태는 무엇입니까?


4
귀하의 연구를 공유하면 모든 사람을 도울 수 있습니다. 당신이 무엇을 시도했고 왜 그것이 당신의 요구를 충족시키지 못했는지 알려주십시오. 이것은 당신이 시간을내어 자신을 돕기 위해 노력했고, 명백한 답변을 되풀이하는 것을 막아 주며, 무엇보다도보다 구체적이고 적절한 답변을 얻는 데 도움이됩니다. 또한 물어
gnat

답변:


46

값 (숫자, 문자열, 복잡한 데이터 구조)을 ID 및 특정 시점에 연결할 때 상태가됩니다.

예를 들어, 숫자 10 자체는 어떤 상태도 나타내지 않습니다. 잘 정의 된 숫자 일 뿐이며 항상 자연 숫자 10입니다. 다른 예로, 문자열 "HELLO"는 5 자의 시퀀스입니다. 포함 된 문자와 표시 순서로 완전히 설명됩니다. 500 만 년 후에 문자열 "HELLO"는 여전히 문자열 "HELLO"가됩니다 : 순수한 값.

국가를 갖기 위해서는 이러한 순수한 가치가 정체성 을 가진 어떤 종류의 실체와 관련이있는 세계를 고려해야합니다 . 정체성은 기본적인 아이디어입니다. 즉, 다른 속성에 관계없이 두 가지를 구별 할 수 있습니다. 예를 들어, 동일한 모델, 동일한 색상의 두 대의 자동차는 서로 다른 두 대의 자동차입니다.

이러한 것들이 동일하게 주어지면 순수한 값으로 설명되는 속성을 속성에 첨부 할 수 있습니다. 예를 들어, 내 차는 파란색이됩니다. 쌍을 연결하여이 사실을 설명 할 수 있습니다

("colour", "blue")

내 차에 쌍 ( "컬러", "파란색")은 해당 자동차 의 상태 를 설명하는 순수한 값 입니다.

국가는 특정 실체뿐만 아니라 특정 시점과도 관련이 있습니다. 오늘 내 차에는 상태가 있다고 말할 수 있습니다

("colour", "blue")

내일 나는 검은 색으로 칠하고 새로운 상태는

("colour", "black")

엔터티의 상태는 변경 될 수 있지만 정의에 따라 해당 아이덴티티 는 변경되지 않습니다 . 물론, 실체가 존재하는 한, 자동차는 만들어지고 파괴 될 수 있지만, 일생 동안 정체성을 유지할 것입니다. 아직 존재하지 않거나 더 이상 존재하지 않는 것의 정체성에 대해 말하는 것은 이치에 맞지 않습니다.

주어진 엔터티에 연결된 속성 값이 시간이 지남에 따라 변경되면 해당 엔터티의 상태가 변경 가능 하다고 말합니다 . 그렇지 않으면 상태가 변경 불가능 하다고 말합니다 .

가장 일반적인 구현은 엔티티의 상태를 어떤 종류의 변수 (전역 변수, 객체 멤버 변수)에 저장하는 것입니다. 즉 , 상태 의 현재 스냅 샷 을 저장하는 것 입니다. 그런 다음 할당을 사용하여 가변 상태가 구현됩니다. 각 할당 작업은 이전 스냅 샷을 새 스냅 샷으로 바꿉니다. 이 솔루션은 일반적으로 메모리 위치를 사용하여 현재 스냅 샷을 저장합니다. 메모리 위치를 덮어 쓰는 것은 스냅 샷을 새로운 것으로 대체하는 파괴적인 작업입니다. ( 다음은 이에 대한 흥미로운 이야기 찾을 수있는 장소 지향 프로그래밍 접근 방식을.)

대안은 엔티티의 후속 상태 (이력)를 값의 스트림 (아마도 무한한 순서)으로 보는 것입니다 (예 : SICP의 3 장 참조) . 이 경우 각 스냅 샷은 다른 메모리 위치에 저장되며 프로그램은 다른 스냅 샷을 동시에 검사 할 수 있습니다. 사용하지 않는 스냅 샷은 더 이상 필요하지 않은 경우 가비지 수집 할 수 있습니다.

두 가지 접근법의 장단점

  • 접근 방식 1은 메모리를 덜 사용하고 복사가 필요 없으므로 새로운 스냅 샷을보다 효율적으로 구성 할 수 있습니다.
  • 접근법 1은 암시 적으로 새로운 상태를 참조하는 프로그램의 모든 부분으로 푸시합니다. 접근법 2는 예를 들어 이벤트 형태로 관찰자에게 스냅 샷을 푸시하는 메커니즘이 필요합니다.
  • 접근 방식 2는 일관성없는 상태 오류 (예 : 부분 상태 업데이트)를 방지하는 데 도움이됩니다. 이전 상태에서 새 상태를 생성하는 명시 적 함수를 정의하면 다른 시점에서 생성 된 스냅 샷을 쉽게 구분할 수 있습니다.
  • 접근법 (2)가 허용하는 것을 더욱 용이하게되는 모듈과 같은 고차 함수를 이용하여 예를 들어 상태 그 자체의 독립적 인 온 상태보기를 생성 map하고 filter.

1
객체가 상태를 가진 유일한 것은 아닙니다. 프로그램이 (변경 가능) 전역 변수를 사용하는 경우 프로그램 자체에 상태가 있다고합니다. 마찬가지로 함수에 함수 호출에서 값을 기억하는 변수가 있으면 함수는 상태 저장입니다.
Doval

2
@Doval : 전역 상태를 전역 세계 객체의 상태로 생각할 수 있습니다. 내가 아는 한이 뷰는 Ruby에서 사용됩니다. 상태를 기억하는 함수는 단 하나의 방법으로 객체와 동형입니다. 일반적인 기본 아이디어는 값을 ID 또는 장소에 연결하는 것입니다. 즉, 특정 사물은 값을 보유 할 수 있지만 (변경 가능한 값일 수는 있음) ID를 유지합니다.
Giorgio

3
물론 원칙적으로 동의합니다. 나는 단지 Prog가 statefulness가 OOP에만 국한된 것이 아님을 이해하도록하고 있습니다. 나는 "모든 것이 대상이다"라는 생각의 선이 자연스럽게 온다고 생각하지 않습니다.
Doval

@ Doval : 다른 호출에서 값을 기억하는 상태 저장 함수를 언급했습니다. 내가 생각할 수있는 한 가지 예는 C의 정적 로컬 변수입니다. 또 다른 예는 클로저 (컨텍스트에 정의 된 변수를 캡처하는 함수)입니다. 클로저는 객체에 다소 이중적입니다. 클로저는 정확히 하나의 방법을 사용하는 객체 인 반면 객체는 동일한 변수에 대해 정의 된 클로저의 모음입니다. 아마이 모든 것을 알고 있지만 여기에 요약하고 싶었습니다. 일반적으로 지적한대로 일부 메모리 위치에 상태를 저장하고 다른 메커니즘을 사용하여 액세스 할 수 있습니다.
Giorgio

11

상태는 단순히 메모리에 저장된 것에 대한 정보입니다.

객체 지향의 간단한 연습으로 클래스를 쿠키 커터로, 쿠키를 객체로 생각하십시오. 쿠키 커터 (클래스)를 사용하여 쿠키를 생성 (객체 인스턴스화) 할 수 있습니다. 쿠키의 속성 중 하나는 색상입니다 (식품 색상을 사용하여 변경할 수 있음). 해당 쿠키의 색상은 다른 속성과 마찬가지로 상태의 일부입니다.

가변 상태는 객체 (쿠키)를 만든 후 변경할 수있는 상태입니다. 불변 상태는 변경할 수없는 상태입니다.

동시성, 컴퓨터에서 둘 이상의 프로세서가 동시에 해당 개체에서 작동 할 수있는 기능을 처리 할 때는 변경 불가능한 개체 ( 상태를 변경할 수 없는 개체 )가 중요해 집니다. 불변성은 객체의 수명 동안 안정적이고 유효한 상태에 의존 할 수 있도록 보장합니다.

일반적으로 객체의 상태는 "개인 또는 멤버 변수"로 유지되고 "속성"또는 getter / setter 메소드를 통해 액세스됩니다.


3
Prog의 이점을 위해 추론하기가 훨씬 쉽기 때문에 가치가 절대 변하지 않는다는 사실도 중요합니다. 원하는만큼 많은 기능 / 방법에 사용할 수 있으며 변경할 수 없다는 것을 알고 있습니다. 변경 가능한 상태를 사용하면 해당 객체가 현재 값을 파악하는 데 사용 된 방법에 대한 기록을 추적해야합니다 . 불변으로 만드는 것이 프로그램을 복잡하게하지 않으면 불필요하게 정신적 인 오버 헤드입니다.
Doval

대답 해줘서 고마워. 그래서 기본적으로 OOP에서 누군가가 '상태'라고 말할 때 보통 "객체의 구성원 변수"를 의미합니까? 그렇다면 'mutable state'는 공용 변수이거나 OOP에서는 setter 메소드를 통해 변경할 수있는 private 변수입니다. 'immutable state'는 단순히 private 멤버 변수입니까?
Aviv Cohn

1
초기 값으로 채워진 개체의 개인 멤버에 절대 쓰지 않기 만하면 불변성을 시뮬레이션 할 수 있습니다 . 불변성 수 적용 세터 방법을 제공하지 않는 등의 상수를 사용하여 기능적 스타일 작성 생성자 파라미터를 이용하여 설정되는 초기 값을 필요 : 다수의 방법을 이용하여
로버트 하비

1
나는 국가를 어떤 실체의 어떤 재산의 가치로 생각한다. "배송 됨"은 상태입니다. "세금율"도 마찬가지입니다. 무언가의 무게는 상태입니다. 현재 깨어 있는지 아니면 잠든 상태입니다. 무언가의 색은 상태입니다. 어떤 종류의 컴퓨터 메모리에 보유 된 무언가에 대한 의미있는 정보.
Robert Harvey

1
많은 언어에서 멤버 변수를 "const"또는 "final"로 선언하면 불변성을 적용 할 수 있습니다. 이러한 변수는 생성자 만 초기화 할 수 있습니다. 개인 변수는 변경할 수 없다고 가정하지 마십시오. 클래스의 자체 멤버 함수 (메서드)로 계속 수정할 수 있습니다.
Simon B

7

스테이트 풀 API를 스테이트리스 API와 비교할 때 "상태"라는 용어 ( "구성원 변수"와 같은 구체적인 유형의 상태와 반대)가 가장 유용하다고 생각합니다. API를 언급하지 않고 "상태"를 정의하는 것은 프로그래밍 언어를 언급하지 않고 "변수"또는 "함수"를 정의하는 것과 약간 비슷합니다. 정답의 대부분은 단어의 의미를 이미 알고있는 사람들에게만 의미가 있습니다.

상태 저장 대 상태 비 저장

  • 상태 API는 함수를 호출 다음 번에이 정보를 사용하는 것, 그래서 지금까지 어떤 인자라고 한 것을 기능 "기억"는 것입니다. "기억하는"부분은 종종 멤버 변수로 구현되지만 이것이 유일한 방법은 아닙니다.
  • 무의 API는 모든 함수 호출만을 전달 된 인수에 의존하지 않고, 아무 것도 하나입니다.

예를 들어, OpenGL은 아마도 내가 알고있는 가장 상태가 좋은 API 일 것입니다. 내가 어리석게 지나치게 단순화하면 다음과 같이 보일 수 있습니다.

glSetCurrentVertexBufferArray(vba1);
glSetCurrentVertexBufferObject(vbo1);
glSetCurrentVertexShader(vert1);
glSetCurrentFragmentShader(frag1);
// a dozen other things
glActuallyDrawStuffWithCurrentState(GL_TRIANGLES);

거의 모든 함수는 OpenGL이 기억해야 할 상태 중 일부를 전달하는 데 사용됩니다. 결국에는 모든 도면을 수행하기 위해 하나의 반기 상적으로 간단한 함수를 호출합니다.

Openless의 상태 비 저장 버전은 아마도 다음과 같습니다.

glActuallyDrawStuff(vba1, vbo1, vert1, frag1, /* a dozen other things */, GL_TRIANGLES);

상태가 낮은 API는 추론하기 쉽다고 사람들이 말하는 경우가 종종 있습니다. 인수 개수를 통제 할 수 있다면 일반적으로 동의합니다.

가변 대 불변

내가 아는 한,이 구별은 초기 상태를 지정할 수있을 때만 의미가 있습니다 . 예를 들어 C ++ 생성자를 사용하는 경우 :

// immutable state
ImmutableWindow windowA = new ImmutableWindow(600, 400);
windowA = new ImmutableWindow(800, 600); // to change the size, I need a whole new window

// mutable state
MutableWindow windowB = new MutableWindow(600, 400);
windowB.width = 800; // to change the size, I just alter the existing object
windowB.height = 600;

크기를 "기억"하지 않는 창 클래스를 구현하기는 어렵지만 사용자가 창 크기를 만든 후 창 크기를 변경할 수 있는지 여부를 결정할 수 있습니다.

PS OOP에서 "상태"는 일반적으로 "구성원 변수"를 의미하지만, 그 이상일 수 있습니다. 예를 들어, C ++에서 메소드는 정적 변수를 가질 수 있으며 람다는 변수를 캡처하여 클로저가 될 수 있습니다. 두 경우 모두 해당 변수는 함수에 대한 여러 호출에서 지속되므로 상태로 간주 될 수 있습니다. 일반 함수의 지역 변수는 사용 방법에 따라 상태로 간주 될 수도 있습니다 (main ()에서 자주 사용하는 변수).


멋진 답변입니다. 정말 고마워요 정말 빨리 데리러 도와 주셨어요 거의 알지 못했습니다. 오랫동안 이것으로 작업 해 왔으며 그것이 무엇인지 몰랐습니다.
the_endian

2

평신도의 말로

사전 상태 :

에이. 상황과 관련된 상태 또는 상태.

  1. 상태-주요 속성과 관련한 방식.

무언가의 상태는 속성이 주어진 순간에 갖는 일련의 값입니다.

OOP에서 객체의 상태는 주어진 순간의 속성 값에 대한 스냅 샷입니다.

Thing t = new Thing();
t.setColor("blue");
t.setPrice(100)
t.setSize("small");

상태는 파란색이고 가격은 100이고 크기는 작습니다.

나중에 할 경우 :

t.setColor("red");

속성 중 하나를 변경하지만 개체가 더 이상 동일하지 않기 때문에 상태 전체를 변경했습니다.

때때로 클래스는 속성 값을 만든 후에 변경할 수 없도록 설계되었습니다. 속성의 모든 값은 생성자에 전달되거나 데이터베이스 또는 파일과 같은 일부 소스에서 읽지 만 "setter"메소드가 없거나 다른 방법이 없으므로 해당 시점 이후에 해당 값을 변경할 방법이 없습니다. 객체 내부의 값을 변경합니다.

Thing t = new Thing("red",100,"small");
t.setColor("blue") -->> ERROR, the programmer didn't provide a setter or any other way to change the properties values after initialization.

이를 돌연변이 상태로 변경할 수없는 상태라고합니다. 당신이 할 수있는 일은 객체를 파괴하고 새로운 객체를 만들고 동일한 참조 또는 변수에 할당하는 것입니다.

Thing t = new Thing("red",100,"small");
t = new Thing("blue",100,"small");
// I had to create a new Thing with another color since this thing is inmutable.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.