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

태그:

카테고리:

업데이트:

댓글남기기