아직 언급되지 않은 주요 요점은 객체의 상태를 변경 가능하게하면 해당 상태를 캡슐화하는 객체 의 ID 를 변경할 수 없다는 것입니다.
많은 프로그램은 본질적으로 변경 가능한 실제 사물을 모델링하도록 설계되었습니다. 오전 12시 51 분에 일부 변수 AllTrucks
에 객체 # 451에 대한 참조가 있다고 가정합니다. 개체 # 451은 해당 시점의 모든 트럭에 어떤화물이 포함되어 있는지 (12:51 am) 데이터 구조의 근본이며 일부 변수는 BobsTruck
객체 # 24601에 대한 참조를 얻는 데 사용할 수있는 것은 해당 순간에 밥 트럭에 어떤화물이 포함되어 있는지를 나타내는 객체를 가리 킵니다 (12:51 am). 오전 12:52에 일부 트럭 (Bob 포함) AllTrucks
이로 드 및 언로드되고, 데이터 구조가 업데이트되어 화물이 모든 트럭에 있음을 나타내는 데이터 구조에 대한 참조를 보유합니다.
어떻게 BobsTruck
됩니까?
각 트럭 개체의 '화물'속성이 변경 불가능한 경우 개체 # 24601은 Bob의 트럭이 오전 12시 51 분에 있었던 상태를 영원히 나타냅니다. BobsTruck
객체 # 24601에 대한 직접 참조를 보유하고 있다면 업데이트하는 코드 AllTrucks
도 업데이트되지 않으면 BobsTruck
Bob의 트럭의 현재 상태를 나타내는 것이 중단됩니다. 또한 BobsTruck
어떤 형태의 변경 가능한 객체에 저장 되지 않는 한 업데이트하는 코드가 업데이트 AllTrucks
할 수 있는 유일한 방법 은 코드가 명시 적으로 프로그래밍 된 경우입니다.
BobsTruck
모든 물체를 불변으로 유지하면서 Bob의 트럭 상태를 관찰하는 데 사용할 수 있기를 원한다면 어떤 특정 시간에 있거나 가진 BobsTruck
값을 고려할 때 불변의 함수 일 수 있습니다 AllTrucks
. 그때. 하나는 불변의 함수 쌍을 가질 수도 있습니다. 그중 하나는 위와 같고 다른 하나는 함대 상태와 새로운 트럭 상태에 대한 참조를 수락하고 새로운 함대 상태에 대한 참조를 반환합니다 Bob의 트럭이 새로운 상태를 가질 것이라는 점을 제외하고는 이전과 일치했습니다.
불행히도, Bob의 트럭 상태에 접근하고자 할 때마다 그러한 기능을 사용해야하는 것은 다소 성 가시고 성 가실 수 있습니다. 대안적인 접근법은 객체 # 24601이 항상 그리고 영원히 (누군가가 그것에 대한 참조를 보유하는 한) Bob의 트럭 의 현재 상태를 나타낼 것이라고 말하는 것 입니다. Bob의 트럭의 현재 상태에 반복적으로 액세스하려는 코드는 매번 시간이 많이 걸리는 기능을 실행할 필요가 없습니다. 객체 # 24601이 Bob의 트럭이라는 것을 찾기 위해 검색 기능을 한 번만 수행하면됩니다. Bob의 트럭의 현재 상태를보고 싶을 때마다 해당 오브젝트에 액세스하십시오.
기능적 접근 방식은 단일 스레드 환경이나 스레드가 데이터를 변경하는 대신 주로 데이터를 관찰하는 다중 스레드 환경에서 이점이 없습니다. 에 포함 된 객체 참조를 복사하는 관찰자 스레드AllTrucks
그런 다음 표시된 트럭 상태를 검사하여 참조를 잡은 순간 모든 트럭의 상태를 확인합니다. 옵저버 스레드가 최신 데이터를보고 싶을 때마다 참조를 다시 가져올 수 있습니다. 반면, 단일 불변 개체로 표현 된 전체 함대 상태를 갖는 것은 각 스레드가 자체 장치에 남겨두면 새로운 "함대 상태"개체를 생성하기 때문에 두 스레드가 서로 다른 트럭을 동시에 업데이트 할 가능성을 배제합니다. 트럭의 새로운 상태와 서로의 오래된 상태. 각 스레드가 변경되지 않은 경우에만 CompareExchange
업데이트 AllTrucks
하는 데 사용하고 실패에 응답하는 경우 정확성이 보장 될 수 있습니다.CompareExchange
상태 오브젝트를 재생성하고 조작을 재 시도함으로써, 하나 이상의 스레드가 동시 쓰기 조작을 시도하면, 모든 쓰레드가 단일 스레드에서 수행 된 것보다 성능이 일반적으로 떨어집니다. 스레드가 이러한 동시 작업을 더 많이 시도할수록 성능이 저하됩니다.
개별 트럭 오브젝트가 변경 가능하지만 변경 불가능한 ID 가있는 경우 멀티 스레드 시나리오가 더 깨끗해집니다. 특정 트럭에서 한 번에 하나의 스레드 만 작동 할 수 있지만 다른 트럭에서 작동하는 스레드는 간섭없이 작동 할 수 있습니다. 불변 객체를 사용하는 경우에도 이러한 동작을 에뮬레이트 할 수있는 방법이 있지만 (예 : "AllTrucks"객체를 정의하여 XXX에 속하는 트럭의 상태를 SSS로 설정하려면 "As of [Time], [XXX]에 속하는 트럭의 상태는 이제 [SSS]입니다. 그 밖의 모든 상태는 [Old value of AllTrucks] "입니다. 이러한 개체를 생성하는 것은 경합이있을 때에도 충분히 빠릅니다.CompareExchange
루프는 오래 걸리지 않을 것입니다. 다른 한편으로, 이러한 데이터 구조를 사용하면 특정 사람의 트럭을 찾는 데 필요한 시간이 실질적으로 증가합니다. 변경 불가능한 ID를 가진 변경 가능한 오브젝트를 사용 하면 해당 문제점을 피할 수 있습니다.