조금 더 복잡하고 의미있는 예제를 통해서 불변 객체의 사용 예를 확인해보자.
앞의 Address , ImmutableAddress 를 그대로 활용한다.
변경 클래스 사용
package lang.immutable.address;
public class MemberV1 {
private String name;
private Address address;
public MemberV1(String name, Address address) {
this.name = name;
this.address = address;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\\'' +
", address=" + address +'}';
}
}
MemberV1 은 변경 가능한 Address 클래스를 사용한다.
package lang.immutable.address;
public class MemberMainV1 {
public static void main(String[] args) {
Address address = new Address("서울");
MemberV1 memberA = new MemberV1("회원A", address);
MemberV1 memberB = new MemberV1("회원B", address);
//회원A, 회원B의 처음 주소는 모두 서울
System.out.println("memberA = " + memberA);
System.out.println("memberB = " + memberB);
//회원B의 주소를 부산으로 변경해야함
memberB.getAddress().setValue("부산");
System.out.println("부산 -> memberB.address");
System.out.println("memberA = " + memberA);
System.out.println("memberB = " + memberB);
}
}
회원A 와 회원B 는 둘다 서울에 살고 있다.
중간에 회원B 의 주소를 부산으로 변경해야 한다.
그런데 회원A 와 회원B 는 같은 Address 인스턴스를 참조하고 있다.
회원B 의 주소를 부산으로 변경하는 순간 회원A 의 주소도 부산으로 변경된다.
실행 결과
memberA = Member{name='회원A', address=Address{value='서울'}}
memberB = Member{name='회원B', address=Address{value='서울'}}
부산 -> memberB.address
memberA = Member{name='회원A', address=Address{value='부산'}}
memberB = Member{name='회원B', address=Address{value='부산'}}
사이드 이펙트가 발생해서 회원B 뿐만 아니라 회원A의 주소도 부산으로 변경된다.
불변 클래스 사용
package lang.immutable.address;
public class MemberV2 {
private String name;
private ImmutableAddress address;
public MemberV2(String name, ImmutableAddress address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public ImmutableAddress getAddress() {
return address;
}
public void setAddress(ImmutableAddress address) {
this.address = address;
}
@Override
public String toString() {
return "Member{" +
"name='" + name + '\\'' +
", address=" + address + '}';
}
}
MemberV2 는 주소를 변경할 수 없는, 불변인 ImmutableAddress 를 사용한다.
package lang.immutable.address;
public class MemberMainV2 {
public static void main(String[] args) {
ImmutableAddress address = new ImmutableAddress("서울");
MemberV2 memberA = new MemberV2("회원A", address);
MemberV2 memberB = new MemberV2("회원B", address);
//회원A, 회원B의 처음 주소는 모두 서울
System.out.println("memberA = " + memberA);
System.out.println("memberB = " + memberB);
//회원B의 주소를 부산으로 변경해야함
//memberB.getAddress().setValue("부산"); //컴파일 오류
memberB.setAddress(new ImmutableAddress("부산"));
System.out.println("부산 -> memberB.address");
System.out.println("memberA = " + memberA);
System.out.println("memberB = " + memberB);
}
}