불변 객체 - 예제

조금 더 복잡하고 의미있는 예제를 통해서 불변 객체의 사용 예를 확인해보자.

앞의 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);

			}
}
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);

			}
}