상세 컨텐츠

본문 제목

어서션(assert) 리팩토링

자바강좌/리팩토링

by somiyuralove 2020. 1. 18. 15:34

본문

어서션 도입(Introduce Assertion) 리팩토링의 정의를 알아봅시다.
- 어서션이라는 기법으로 프로그래머의 의도를 확실히 밝히면서도 실행시 조건이 반드시 성립함을 보장

프로그램의 어떤 부분에서 변수 value값이 참이어야고 한다면, value값이 참이 아니라면 프로그래머의 의도와는 다른 동작을 합니다. 

'value값이 참이어야 한다'를 자바에서는 assert value > 0;

프로그램을 실제로 동작시켜 자바 실행 환경이 어서션을 실행할때 value > 0이라면 아무일도 일어나지 않습니다..

하지만 만약에 value > 0이 아니라면 자바 실행 환경은 java.lang.AssertionError 예외를 던집니다.

이 예외는 프로그래머가 표명한 조건식이 성립되지 않았다라는 뜻을 나타냅니다.

아래 예제코드는 어서션을 도입하기전 예제코드입니다. 주석으로 처리된 부분이 어서션을 도입해야할 곳입니다.

 

* SortSample.java

 

package SortSample;

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() {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
for (int i=0; i<_data.length; i++) {
buffer.append(_data[i]);
buffer.append(", ");
}
buffer.append("]");
return buffer.toString();
}

}

 

* Main.java

 

package SortSample;

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);
}
}

 

그리고, 아래 코드는 어서션이 적용되 코드입니다.

package SortSample;

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;
}
}

assert isMin(m, x, _data.length-1);
int v = _data[m];
_data[m] = _data[x];
_data[x] = v;
assert isSorted(0, x+1);
}

}

public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
for (int i=0; i<_data.length; i++) {
buffer.append(_data[i]);
buffer.append(", ");
}
buffer.append("]");
return buffer.toString();
}

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;
}

}

 

* 어서션이 도입된 코드

package SortSample;

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;
}
}

assert isMin(m, x, _data.length-1);
int v = _data[m];
_data[m] = _data[x];
_data[x] = v;
assert isSorted(0, x+1);
}

}

public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
for (int i=0; i<_data.length; i++) {
buffer.append(_data[i]);
buffer.append(", ");
}
buffer.append("]");
return buffer.toString();
}

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옵션을 지정해야 합니다. ( javac Main.java, java -ea Main ) 

-ea는 -enableassertions의 약어입니다. 이 옵션이 없으면 어서션이 비활성화되어 assert 문은 모두 무시됩니다.

어서션에 대한 자세한 내용은 아래를 참고하세요.

https://docs.oracle.com/javac/8/docs/technotes/guides/language/assert.html

 

 

 

관련글 더보기

댓글 영역