코드에서 변수는 중요한 역할을 합니다.
처음 코드를 스캔할 때 이 변수가 어떤 의미인지 추론하게 되고 어떤 역할을 하는지 알 수 있기 때문입니다.
단순히 그렇게만 생각하고 있었는데, 이 책을 읽던 중 요르마 사야니에미 교수가 정의한 11개의 역할을 알게 되었고, 각 변수가 어떤 역할을 하는지 정리를 해준다. 코드에서 변수 이름에 역할명을 포함하면 변수명이 길어진다는 단점이 있지만 변수에 중요한 정보를 전달할 수 있고, 코드를 읽을 개발자가 변수의 역할을 파악할 때 수고로움을 덜 수 있습니다.
요르마 사야니에미 교수에 따르면, 변수를 이해하기 어려운 이유는 대부분의 프로그래머가 변수를 연관 지을 스키마를 자신들의 LTM에 가지고 있지 않기 때문입니다. 우리는 너무 구체적인 변수명 또는 너무 적은 것을 포함하는 청크를 사용하는 경향이 있다고 합니다. 많고 적음. 이 중간이 필요한데, 이것이 사야니에미로 하여금 변수 역할이라는 프레임워크를 만드는 동기가 되었고, 변수의 역할은 프로그램 내에서 변수가 하고자 하는 바를 나타낸다고 합니다.
그러면 요르마 사야니에미 교수가 정의한 11가지 역할에 대해 살펴보겠습니다.
11가지 역할
- 고정값(fixed value)
초기화를 통해 값이 할당된 이후 값이 변경되지 않는 변수
//값이 고정하는 것이 가능한 프로그래밍 언어를 사용한다면 상수
final int MIN = 1;
/**
* 그렇지 않다면 한번 초기화 되고 난 이후에 다시는 변경되지 않는 변수
* EX) 파이 같은 수학 상수 혹은 파일이나 데이터베이스에서 읽어 들인 데이터의 값
*/
double pie=3.14;
- 스테퍼(stepper)
- 루프를 반복 실행하며 값이 단계적으로 변하는 변수
- 또는 아래 예제 처럼 복잡 스테퍼 또한 가능하다.
/**
* 이진 검색에서 반복마다 배열의 크기를 반씩 줄여나가는 데 사용하는
* mid = (low + high) / 2처럼
* 좀 더 복잡한 스테퍼 또한 가능
*/
int mid;
while(low <= high) {
mid = (low + high) / 2;
if(arr[mid] == key)
return mid;
else if( arr[mid] < key)
high = mid - 1;
else
low = mid + 1;
}
return -1;
- 플래그(flag)
무엇인가 발생했거나 어떤 경우에 해당하는지를 나태는 변수
플래그 변수는 주로 불리언 변수지만 정수 혹은 문자열도 가능하다.
boolean hasBeenBelowZero = true;
if(num < 0) hasBeenBelowZero = false;
- 워커(walker)
스테퍼와 유사하게 자료구조를 순회한다. 스테퍼와의 차이점은 자료구조를 순회하는 방식이다.
스테퍼는 for처럼 항상 미리 정해진 값을 따라 반복하지만 워커는 일단 루프가 시작되기 전에는 어떤 값을 가지게 될지 알 수 없다.
프로그래밍 언어에 따라 포인터나 정수 인덱스가 워커로 사용될 수 있다.
이진 검색에서 리스트를 순회하기 위해 사용할 수도 있지만 스택이나 트리를 순회하는 데 사용될 때가 많다.
연결 리스트(linked list)에 새로운 값을 추가할 위치를 찾을 때 사용하거나 이진트리에서 사용되는 검색 인덱스가 워커 변수의 예다.
boolean hasCycle(ListNode head) {
if(head == null) {
return false;
}
ListNode walker = head;
ListNode runner = head;
while(runner.next!=null && runner.next.next!=null) {
walker = walker.next;
runner = runner.next.next;
if(walker==runner) return true;
}
return false;
}
- 최근 값 보유자(most recent holder)
어떤 값이 변해갈 때 가장 최근에 변경된 값을 갖는 변수
/*
* 입력이 유효할 때까지 사용자에게 입력을 요청하는데,
* 변수num은 가장 최근 입력한 값을 보유하고 있기 때문에
* 가장 최근 보유자입니다.
*/
int num = 0;
while (num <=0) {
System.out.print("0보다 큰 숫자를 값을 입력하세요 : ");
num = stdIn.nextInt();
}
System.out.printf("입력한 값은 = %d입니다", num);
//배열에서 스테퍼가 가리키는 원소의 사본을 저장하는 변수
element = list[i];
//파일을 한 줄씩 읽어 들일 때 가장 마지막으로 읽은 줄을 저장하는 변수
line = file.readLine()
- 목적 값 보유자(most wanted holder)
어떤 값을 처리하는 과정에서 찾고자 하는 조건에 부합하는 값을 갖는 변수
최솟값이나 최댓값, 혹은 어떤 조건을 만족하는 첫 번째 값 등
//max : most-wanted holder
int[] arr = {3,2,3,4,5,6,7,8,9,10};
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max)
max = arr[i];
}
System.out.printf("최댓값은 %d입니다", max);
- 모집자(gatherer)
데이터를 모으거나 모은 데이터에 대해 어떤 연산을 수행하여 얻은 값을 저장하는 변수
int[] arr = {3, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = 0;
for (int i = 0; i < arr.length; i++)
sum += arr[i];
System.out.printf("총합 : %d", sum);
- 컨테이너(container)
값을 새로 추가하거나 삭제할 수 있는 자료구조라면 어떤 것이라도 컨테이너 변수
예) 리스트 배열, 스택, 트리에 대한 변수는 모두 컨테이너다
Stack<Integer> stack = new Stack<>();
- 추적자(follower)
이전 값 혹은 다음 값을 추적해야 할 필요가 있을 때 이런 역할을 수행하는 변수
추적자는 항상 다른 변수에 연관되어 있다
/**
* 두 수의 가장 큰 차이를 구하는 프로그램
* previous가 추적자 변수 역할을 수행한다
*/
System.out.print("1번째 값 : ");
int previous = stdIn.nextInt();
System.out.print("2번째 값 : ");
int current = stdIn.nextInt();
int biggestDiff = current - previous;
for (int i = 3; i <= 6; i++) {
previous = current;
System.out.print(i+"번째 값 : ");
current = stdIn.nextInt();
if(current - previous > biggestDiff)
biggestDiff = current - previous;
}
System.out.print(biggestDiff);
- 조직자(organizer)
초기화 후 요소를 재구성하는 데 사용되는 변수
때론 추가적인 처리를 위해 변수의 값을 변환해야 하는데, 어떤 프로그래밍 언어에서는 문자열 내 개별 문자에 접근하려면 먼저 배열로 변환해야 한다. 혹은 주어진 리스트를 정렬한 결과를 따로 가지고 있어야 할 수 있다. 이렇게 다른 값을 저장하기 위한 목적으로 사용하는 변수를 조직자라고 하며 조직자는 종종 임시 변수이기도 하다.
/**
* 배열을 역순으로 돌리기
* arr : organizer
* temp : temporary
*/
int[] arr = {1,2,3,4,5,6,7,8,9,10};
int temp;
for (int i = 0; i < arr.length/2; i++) {
temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
- 임시(temporay)
임시 변수는 잠시만 사용하기 위한 변수
데이터를 맞바꾸거나 메서드나 함수에 여러 번 사용되는 계산의 결과를 저장할 때 사용
이렇게 사야니에미가 정의한 11개의 역할에 대해 예제와 함께 알아봤습니다!
보다 더 각 변수가 어떤 역할을 하는지 이해하는 데 도움이 될 수 있게 순서도를 사용해서 변수의 코드 내 역할을 판별해보겠습니다!
그리고 신기하게도 이 책의 필자는 변수 역할마다 아이콘을 사용한다고 나와있습니다.
그래서 변수 역할들의 아이콘을 외우면 강력한 기억 보조 도구로 사용할 수 있기 때문에 참고하시면 좋을 듯합니다!
느낀 점
변수에 역할에 대해 다시 한번 생각해보게 되었다.
코드를 작성할 때 변수 이름이 길어지기 때문에 호불호가 있을 거라고 생각하지만, 각 변수 역할에 대해 생각하면서 코드를 작성하는 것이 중요하다고 느꼈다.
또한, 책에는 각 변수 역할에 대해 예제가 거의 나와있지 않아
나중에 나 또는 다른 사람이 보더라도 조금이나마 이해가 될 수 있게
어떤 식으로 예제를 쓰면 좋을지 고민해서 재밌기도 했다.
[참고]
http://saja.kapsi.fi/var_roles/stud_vers/stud_Java_eng_v1.html
http://saja.kapsi.fi/var_roles/stud_vers/stud_Java_eng.html
'책 > 기록' 카테고리의 다른 글
[Effective Java] 아이템2 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2022.06.18 |
---|---|
[Effective Java] 아이템1 생성자 대신 정적 팩토리 메서드를 고려하라 (0) | 2022.06.16 |
개발자에서 아키텍트로 #3 -설계-전략-고안하기 (0) | 2021.08.04 |
개발자에서 아키텍트로 #2 - 디자인 싱킹 기초 (0) | 2021.07.05 |
개발자에서 아키텍트로 #1 소프트웨어 아키텍트가 되다 (0) | 2021.07.01 |