[Java] 객체의 상태를 외부에서 조작할 수 있는 가능성을 없애는 방법은? (방어적 복사, 불변 컬렉션)
1. Question
객체의 상태를 외부에서 조작할 수 있는 가능성을 없애는 방법은?
2. Answer
A. 방어적 복사
입력받을 때 방어적 복사를 사용하면, 객체가 외부에서 받은 데이터로 초기화될 때, 이 데이터가 외부에서 변경되더라도 객체 내부의 상태는 변경되지 않는다. 이를 통해 객체의 무결성을 유지할 수 있다.
public class DefensiveCopyInput {
private List<String> items;
public DefensiveCopyInput(List<String> initialItems) {
// 방어적 복사를 사용하여 외부 리스트의 변화가 이 객체에 영향을 미치지 않도록 한다.
this.items = new ArrayList<>(initialItems);
}
}
B. 불변 컬렉션으로 선언
응답을 할 때 컬렉션을 불변으로 만들어 반환하면, 이 컬렉션을 받는 클라이언트가 컬렉션의 내용을 변경할 수 없게 된다. 이는 Collections.unmodifiableList
와 같은 메서드를 사용하여 구현할 수 있다.
public class UnmodifiableResponse {
private List<String> items;
// items 리스트에 대한 변경 불가능한 뷰를 제공한다.
public List<String> getItems() {
return Collections.unmodifiableList(items);
}
}
3. Detail
A. 방어적 복사의 특징
-
방어적 복사는 객체의 데이터를 복사하여 새로운 객체를 생성하는 방법이다. 이는 원본 객체와 복사된 객체가 서로 다른 메모리를 차지하게 만들어, 한 객체의 변경이 다른 객체에 영향을 미치지 않도록 한다.
-
방어적 복사를 사용하면, 객체 내부의 데이터를 외부에서 직접적으로 변경할 수 없게 만든다. 외부에서 객체의 상태를 변경하려 할 때, 실제 객체가 아닌 그 복사본이 변경되기 때문에 원본 객체는 안전하게 보호된다.
-
이 방식은 특히 변경 가능한(mutable) 객체를 다룰 때 유용하며, 객체의 완전한 독립성을 보장한다. 하지만, 객체를 복사하는 데 추가적인 메모리와 처리 시간이 필요하다.
B. 불변 뷰의 특징
-
불변 뷰는 컬렉션에 대한 읽기 전용의 접근을 제공한다. 이 뷰를 통해 컬렉션의 내용을 변경하려고 하면 예외가 발생한다. 그러나 이 뷰는 원본 컬렉션과 동일한 데이터를 참조한다.
-
불변 뷰를 사용하면 원본 컬렉션의 데이터 보호는 가능하지만, 뷰 자체는 원본 데이터와 동일한 참조를 가지고 있기 때문에, 원본 컬렉션 자체가 변경되면 뷰도 영향을 받는다.
-
이 방식은 컬렉션의 데이터를 보호하면서도 추가적인 메모리 사용 없이 뷰를 제공하고 싶을 때 유용하다. 다만, 원본 컬렉션의 변경을 완전히 차단하지는 못한다.
4. Reference
None
댓글남기기