불변성

송민준·2024년 7월 14일
1

OOP

목록 보기
4/4

불변성에는 여러 의미가 있지만 "객체"의 불변성에 대해 글을 작성하고자 한다.

불변성

아래 User는 닉네임을 전부 대문자로 변경하는 책임이 있다고 가정하면 아래 코드가 나올 수 있겠다.

class User {
	public String nickName;
    public User(String nickName) {
    	this.nickName = getUpperNickName(nickName);
    }
  	private String getUpperNickName(Sting nickName) {
    	this.nickName = nickName.toUpperCase();
    }
}

User는 생성자에서 닉네임을 대문자로 변경한다.

불변성이란 그 객체가 항상 참이어야 하는 조건이다. 이 User는 닉네임이 항상 대문자여야하는 불변성이 있다.
현재 User는 불변성을 만족할까?

그렇지않다. User 객체를 사용하는 클라이언트 코드는 다음과 같은 식으로 User의 불변성을 위반할 수 있다. (불변성 위반) 닉네임을 변경하는 코드이다.

{
	user.nickName = requestNickName; // "hongGilDong"
}

User의 nickName은 항상 대문자가 되어야 하지만 위 코드로 그렇지 않게 되었다.

{	
	String upperNickName = requestNickName.toUpperCase();
	user.nickName = upperNickName; // "HONGGILDONG"
}

물론 위와 같은 방식으로 대문자를 만든 뒤 집어넣을 수 있지만 이 User 객체를 사용하는 모든 클라이언트가 이 두가지 동작을 수행한다고 보장할 수 있을까. 분명 그렇지 않을 것이고 여럿이서 작업한다면 더욱이 그렇지 않을 것이다.

왜 불변성위반이 나타날까.
클라이언트는 User 객체가 해줬으면 하는 것은 단지 "닉네임을 설정하는 것"이다. 그렇다면 생성자만으로도 충분하다.

class User {
	private String nickName; // public -> private
    public User(String nickName) {
    	this.nickName = getUpperNickName(nickName);
    }
  	private String getUpperNickName(Sting nickName) {
    	this.nickName = nickName.toUpperCase();
    }
}

닉네임 변경도 생성자와 같은 방식으로 대문자로 설정되도록 하면 불변성은 위반되지 않을 것이다.

불변성 위반 식별

불변성을 위반이 되었는 지 식별하는 좋은 방법이 있다.
방금의 위반되는 코드를 가지고 왔다.

{	
	String upperNickName = requestNickName.toUpperCase();
	user.nickName = upperNickName; // "HONGGILDONG"
}

클라이언트에서 User 객체를 활용할 때 단 한줄의 코드로 동작시킬 수 없는 것을 볼 수 있다.
이는 User 객체의 캡슐화가 되지 않았다는 뜻이며 클라이언트는가 User의 책임을 동시에 갖고 있다는 뜻이다.

{
	user.updateNickName(requestNickName);
}

User의 캡슐화가 잘 되었다면 단 한줄로도 이용이 가능할 것이다.

물론 무조건 한줄이 아니면 불변성 위반이라는 것은 아니다

reference

  • 단위테스트 - 블라디미르 코리코프
profile
개발자

0개의 댓글