Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

아이템 76. 가능한 한 실패 원자적으로 만들라 #78

Open
HanaHww2 opened this issue Apr 18, 2023 · 1 comment
Open

아이템 76. 가능한 한 실패 원자적으로 만들라 #78

HanaHww2 opened this issue Apr 18, 2023 · 1 comment
Assignees

Comments

@HanaHww2
Copy link
Contributor

No description provided.

@YunDaHyee
Copy link
Contributor

YunDaHyee commented May 2, 2023

아이템 76. 가능한 한 실패 원자적으로 만들라

실패 원자적(failure-atomic)

호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지하는 특성

메서드를 실패 원자적으로 만드는 방법

불변 객체(아이템 17)로 설계하는 방법

  • 불변 객체는 태생적으로 실패 원자적인 특성을 가진다.
    • 이유 : 기존에 존재하는 불변 객체의 상태는 생성 시점에 고정돼서 불변

가변 객체의 메서드를 대상으로 하는 방법

  • 작업 수행에 앞서 매개변수의 유효성을 검사하는 방법(아이템 49)
    • 잠재적인 예외 가능성이 있는 것들을 객체의 내부 상태를 변경하기 전에 대부분 걸러낼 수 있다.
    • 예제 - Stack.pop()
      아래의 소스에서 '이 부분'을 지우더라도 스택 비면 여전히 예외를 던지지만
      size의 값이 음수가 돼서 다음번 호출도 실패하게 만들고
      추상화 수준이 상황에 어울리지 않는 ArrayIndexOutOfBOundsException을 던지게 된다.
      public Object pop() {
          if (size == 0) throw new EmptyStackException(); // 이 부분
          Object result = elements[--sizel;
          elements[sizel = null; // 다 쓴 침조 해제
          return result;
      }
  • 실패할 가능성이 있는 모든 코드를, 객체의 상태를 바꾸는 코드보다 앞에 배치하는 방법
    • 계산을 수행해보기 전에는 인수의 유효성을 검사해볼 수 없을 때 앞선 방식에다가 덧붙여 쓸 수 있다.
    • 예제 - TreeMap
      • 원소들을 어떤 기준으로 정렬하는 특징을 가짐.
      • 해당 객체에 추가할 수 있는 원소 타입 : TreeMap의 기준에 따라 비교할 수 있는 타입
        • 일치하지 않는 원소 추가 시, 원소 삽입 위치 탐색 도중, ClassCastException 던짐

객체의 임시 복사본에서의 작업이 성공하면 원래 객체와 교체하는 방법

  • 데이터를 임시 자료구조에 저장해서 작업하는 게 더 빠를 때 적용하기 좋다.
  • 예제
    • 어떤 정렬 메서드에서 정렬 수행 전에 입력 리스트의 원소들을 배열로 옮겨담을 때 배열을 사용하면, 정렬 알고리즘의 반복문에서 원소들에 훨씬 빠르게 접근할 수 있다.
      => 성능을 높이고 입력 리스트는 변하지 않게 할 수 있다.

작업 도중 발생하는 실패를 가로채는 복구 코드를 작성해서 작업 전 상태로 되돌리는 방법

  • 자주 쓰이진 않지만 주로 (디스크 기반의) 내구성(durability)를 보장해야 하는 자료구조에 쓰인다.

특징

  • 권장되는 특성이지만 항상 만족할 수 있는 특성은 아니다.

    • 예제
      두 스레드가 동기화 없이 같은 객체를 동시 수정한다면 그 객체의 일관성이 깨져서
      ConcurrentModificationException을 발생된다.
      그렇다 해도 그 객체가 여전히 쓸 수 있는 상태라고 가정해서는 안된다.
      에러는 복구할 수 없으므로 AssertionError에 대해 실패원자적으로 만들려는 시도조차 ㅏㄹ 필요 없다..(??)
  • 항상 권장되는 특성이 아니다.

    • 이유 - 비용이나 복잡도가 큰 연산도 존재
    • 하지만 문제가 무엇인지 알고 나면 실패 원자성을 얻어걸릴 수 있다.
  • 메서드 명세에 기술한 예외라면 예외가 발생한다 해도, 실패 원자성을 가져야한다.
    그렇지 않다면 실패 시의 객체 상태를 API 설명에 명시해야 하지만 이는 이상적이고 현실적으론 API 문서 상 잘 지켜지지 안혹 있음.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants