저번시간에 임베디드 타입 에 대해 배웠다.
임베디드 타입의 장점을 알아봤으니 단점을 알아보자
임베디드 타입 같은 값 타입을 여러 엔티티에서 공유하면 사이드 이펙트가 발생해 위험하다
공통점을 묶어 같은 클래스 안에 있으니 한 쪽에서 값을 바꾸면 다른 한쪽도 바뀌는 현상이 발생한다.( =같은 참조 값 때문)
값 타입의 실제 인스턴스 값을 공유하는것은 위험하다
대신 값(인스턴스) 를 복사해서 사용하자
이렇게 같은 인스턴스를 참조하는 값들중에 하나를 변경하면 다른 한쪽도 변경된다(사이드 이펙트 발생)
공유 참조 문제 발생
똑같은 인스턴스를 참조하지말고 다른 복사 인스턴스를 만들어 다른 하나는 복사 인스턴스를 참조 하도록하자
이렇게 만들면 한쪽을 변경해도 두 값이 가르키는 참조값이 다르므로 변경한 쪽만 변경이 된다.
항상 값을 복사해서 사용하면 공유 참조로 인해 발생하는 부작용
을 피할 수 있다.
문제는 임베디드 타입처럼 직접 정의한 값 타입은 자바의 기본
타입이 아니라 객체 타입이다.
- 자바 기본 타입에 값을 대입하여 값을 복사-> 객체 타입은 참조 값을 직접 대입하는 것(setter)을 막을 방법이 없다.
객체 타입을 수정할 수 없게 만들면 부작용 차단
값 타입은 불변 객체 로 설계해야함
생성자로만 값 설정/ Setter는 만들지 말자 ->생성자로 만들어 참조값 다르게 하기
(Integer, String은 불변객체)
불변객체, Setter도 없는 상황에서는 어떻게 값을 변경 할까??
할수없이 인스턴스를 통째로 다시 만드는 방법밖에 없다.
기본타입은 공유 참조 문제가 발생하지 않는다. b를 바꿔도 a는 여전히 10이다.
객체 타입은 공유 참조 문제가 발생한다. 왜냐하면 같은 인스턴스를 가르키기 때문에 그값이 바뀌면 다른 한쪽도 바뀌게 된다.
일반적으로 값 타입은 불변으로 만들어야한다 // 사이드 이펙트 추적하기 어려움
값 타입: 인스턴스가 달라도 그 안에 값이 같으면 같은 것으로 봐
야 함
동일성(identity) 비교: 인스턴스의 참조 값을 비교, == 사용
동등성(equivalence) 비교: 인스턴스의 값을 비교, equals()
사용
값 타입은 a.equals(b)를 사용해서 동등성 비교를 해야 함
-> 예전에 포스팅했던, 자바 초반에 배웠던 Object-equals() 메서드 와 내용이 비슷해서 간략하게만 설명 했다.