[자바로 배우는 리팩토링 입문] 3장 어서션 도입

2022. 4. 15. 03:23·Major/Java
728x90

1. 리팩토링

1) 어서션 도입

- 어서션 : 프로그램의 의도를 확실히 밝히면서 실행 시 조건이 반드시 성립함을 보장

 

2) 리팩토링 카탈로그

이름 어서션 도입(Introduce Assertion)
상황 코드 속에 성립해야 할 조건이 있음
문제 주석으로 ‘이런 조건이 성립한다'라고 적어도 프로그램 실행 시 확인되지 않음
해법 어서션 넣기
결과
o 해당 부분에서 성립해야 할 조건이 명확해지고 소스 코드의 가독성이 좋아짐
o 버그를 빨리 발견 가능함
o 어서션을 활성화하면 어서션이 성립하는지 자동으로 확인 가능함
o 어서션을 비활성화하면 어서션이 무시되어 성능이 개선됨
x 어서션을 지나치게 사용하면 오히려 읽기 어려워짐
주의
• 자바 컴파일러는 어서션을 무효화해도 어서션 부분 코드를 삭제하지 않음
• 어서션 안에 부수효과가 있는 코드를 작성하면 안 됨
• 어서션을 일반 에러 처리 대신에 사용하면 안 됨

 

2. 예제 프로그램

클래스 명 역할
SortSample Int[]를 정렬하는 클래스
Main 동작 확인용 클래스

1) 리팩토링 전

public class SortSample {
    private final int[] _data;

    public SortSample(int[] data) {
        _data = new int[data.length];
        System.arraycopy(data, 0, _data, 0, data.length);
    }

    public void sort() {
        for (int x=0; x < _data.length -1; x++) {
             int m=x;
             for(int y = x + 1; y < _data.length; y++) {
                if (_data[m] > _data[y]) {
                m = y;
                }
              }
        // 여기서 _data[m]은 _data[x] ~ _data[_data.length - 1]의 최솟값이어야 함
        int v = _data[m];
        _data[m] = _data[x];
        _data[x] = v;
        // 여기서 _data[0] ~ _data[x + 1]은 이미 정렬되어 있어야 함
        }
    }
    public String toString() {
        StringBuilder buffer = new StringBuilder(); 
        buffer.append("[ ");
        for (int i = 0; i < _data.length; i++) { 
            buffer.append(_data[i]);
            buffer.append(", ");
        }
        buffer.append("]");
        return buffer.toString();
   }
}

- 선택 정렬을 이용하여 값들을 정렬하는 방식이다.

 

import java.util.Random;
public class Main {
    private static final Random random = new Random(1234);
    private static void execute(int length) {
        //난수로 데이터 작성
        int [] data = new int[length];
        for ( int i=0; i < data.length; i++) {
            data[i] = random.nextInt(data.length);
        }

        //데이터 표시
        SortSample sorter = new SortSample(data);
        System.out.println("BEFORE:" + sorter);

        //정렬해서 표시
        sorter.sort();
        System.out.println(" AFTER:" + sorter);

        System.out.println();
    }

    public static void main(String[] args) {
        execute(10);
        execute(10);
        execute(10);
        execute(10);
        execute(10);
    }
}

 

2) 리팩토링 실행

① 어서션 도입

⑴ 소스 코드에서 '성립해야 할 조건' 찾기

-> SortSample에서 주석처리한 부분

⑵ 조건을 포함한 어서션 작성

assert isMin(m, x, _data.length – 1);
assert isSorted(0, x + 1);
  • isMin(pos, start, end) : 인덱스 pos에 있는 값이 인덱스 start이상 end이하 범위의 값 중에서 최솟값이면 true 반환
  • isSorted(start, end) : 인덱스가 start이상 end이하인 범위가 정렬되어 있으면 true 반환

⭐ 어서션 도입시 부수효과(프로그램 동작 변화)가 없어야 한다.

없어야 하는 이유 : 어서션은 활성화, 비활성화 할 수 있기 때문에 활성화 여부에 따라 객체의 동작에 영향을 주면 안됨

⑶ 적혀 있던 주석 삭제

⑷ 컴파일 해서 테스트

 

3) 리팩토링 후

public void sort() {
    for (int x=0; x < _data.length -1; x++) {
        int m=x;
        for(int y = x + 1; y < _data.length; y++) {
            if (_data[m] > _data[y]) {
            m = y;
            }
        }   
        assert isMin(m, x, _data.length - 1);
        int v = _data[m];
        _data[m] = _data[x];
        _data[x] = v;
        assert isSorted(0, x + 1);
    }
}
...

private boolean isMin(int pos, int start, int end) {
    for(int i = start; i <= end; i++) {
        if(_data[pos] > _data[i]) {
            return false;
        }
    }
    return true;
}

private boolean isSorted(int start, int end) {
    for (int i = start; i < end; i++) {
        if(_data[i] > _data[i+1]) {
            return false;
        }
    }
    return true;
}

- java 명령어 기본값은 어서션 비활성화이기 때문에 -ea 옵션을 지정해야 한다.

 

명령어 옵션 의미
java -ea 어서션을 활성화함(시스템 클래스 제외)
Java -enableassertions 어서션을 활성화함 == -ea
Java -da 어서션을 비활성화함 (시스템 클래스 제외)
java -disableassertions 어서션을 비활성화함 == -da
Java -ea: 클래스명 지정한 클래스로 어서션을 활성화함
Java -ea: .... 지금 작업 디렉터리의 익명 패키지로 어서션을 활성화
java -ea :패키지명 지정한 패키지와 서브 패키지로 어서션을 활성화
Java -da : 클래스명 지정한 클래스로 어서션을 비활성화함
Java -da:... 지금 작업 디렉터리의 익명 패키지로 어서션을 비활성화
Java -da : 패키지명 지정한 패키지와 서브 패키지로 어서션을 비활성화
Java -esa 시스템 클래스로 어서션을 활성화함
Java -enablesystemassertions 시스템 클래스로 어서션을 활성화함 == -esa
Java -dsa 시스템 클래스로 어서션을 비활성화함
Java -disablesystemassertions 시스템 클래스로 어서션을 비활성화함 == -dsa

 

3. 어서션 동작 확인

- 클래스 내에 일부로 에러를 넣어 어서션 동작을 확인할 수 있다.

 

 

4. 한 걸음 더 나아가기

1) 자바 어서션 문법

ⓐ assert expr;

- expr을 평가한다, 평가 결과가 true라면 아무 일도 일어나지 않고, false라면 예외가 발생함

ⓑ assert expr: option;

- expr을 평가, true라면 아무 일도 일어나지 않고, option 표현식도 평가되지 않음

- option 표현식은 expr 값이 false일 때만 평가된다. 부가정보를 제공할 수 있음 (왜 에러가 났는지?)

* exper는 boolean 표현식이고, option 값을 가질 수 있다

 

2) 어서션은 에러 처리를 대신할 수 없음

 

3) 자바 어서션은 클래스 라이브러리가 아님

- assert는 자바 언어 키워드로 취급한다. 왜냐면 클래스 라이브러리가 아닌 자바 언어 사양에 포함되어 있기 때문

 

4) 어서션 완전삭제

- da옵션으로 비활성화 해도 코드는 클래스 파일안에 남아있음 

private static final boolean ASSERT = true // 삭제하려면 false
...
if(ASSERT) {
    assert x>0;
}

- assert문을 if문으로 감싸서 false가 되면 실행되지 않음을 컴파일 시점에서 알수 있어서 조건 컴파일 가능

-> 메모리 절약, 성능 개선에 도움이 된다.

 

5) 다른 언어 환경의 어서션

- C에서 assert 있음

- C++ 에서 템플릿 써서 어서션 실행가능

- C#에는 어서션 기능이 없음

 

5. 정리

어서션은 사람과 컴퓨터 양쪽에 프로그래머의 의도를 전달하는 방법!

코드 안에서 '성립해야 할 조건' 이라면 주석이 아닌 어서션을 도입하자!

728x90
저작자표시 비영리 (새창열림)

'Major > Java' 카테고리의 다른 글

[자바로 배우는 리팩토링 입문] 5장 메서드 추출  (0) 2022.06.01
[자바로 배우는 리팩토링 입문] 4장 널 객체 도입  (0) 2022.04.15
[자바로 배우는 리팩토링 입문] 2장 제어 플래그 삭제  (0) 2022.04.13
[자바로 배우는 리팩토링 입문] 1장 매직 넘버를 기호 상수로 치환  (0) 2022.04.13
[자바로 배우는 리팩토링 입문] 0장 리팩토링이란  (0) 2022.04.13
'Major/Java' 카테고리의 다른 글
  • [자바로 배우는 리팩토링 입문] 5장 메서드 추출
  • [자바로 배우는 리팩토링 입문] 4장 널 객체 도입
  • [자바로 배우는 리팩토링 입문] 2장 제어 플래그 삭제
  • [자바로 배우는 리팩토링 입문] 1장 매직 넘버를 기호 상수로 치환
BeNI
BeNI
코딩하는 블로그
  • BeNI
    코딩못하는컴공
    BeNI
  • 전체
    오늘
    어제
    • Menu (253)
      • My profile (1)
      • 회고 | 후기 (8)
      • Frontend (65)
        • Article (11)
        • Study (35)
        • 프로그래머스 FE 데브코스 (19)
      • Backend (0)
      • Algorithm (58)
        • Solution (46)
        • Study (12)
      • Major (111)
        • C&C++ (23)
        • Java (20)
        • Data Structure (14)
        • Computer Network (12)
        • Database (15)
        • Linux (6)
        • Architecture (3)
        • Lisp (15)
        • OS (1)
        • Security (2)
      • etc (2)
  • 링크

    • 깃허브
    • 방명록
  • 인기 글

  • 최근 댓글

  • 최근 글

  • 태그

    C++
    lisp
    데브코스
    Algorithm
    자료구조
    백준
    파일처리
    프로그래머스
    리팩토링
    react
  • hELLO· Designed By정상우.v4.10.2
BeNI
[자바로 배우는 리팩토링 입문] 3장 어서션 도입
상단으로

티스토리툴바