
사물을 정확하게 이해하기 위해, 여러 측면 가운데 특정 측면을 가려내어 포착하는 것.
⇒ 중요한 정보만 가려내어 남기고, 덜 중요한 정보는 생략하여 버리는 행위.
적절한 추상화는 도메인의 문맥 안에서 핵심 개념만을 표현하는 데 집중하여 복잡한 데이터와 로직을 단순화하고, 이해와 재현을 돕는 과정을 의미합니다. 적절한 추상화에서는 정보를 통해 의미를 유추 및 재현에 성공할 수 있고, 복잡한 데이터 및 로직을 단순화하여 이해하가 쉬워집니다.
도메인의 문맥이란 각 도메인 영역에서 추상화 기준이 다를 수 있다는 뜻입니다. 예를 들어, '지하철'이라는 단어는 미국에서는 "subway", 영국에서는 "underground"라고 표현하는 것처럼, 동일한 개념도 해석자가 공유하는 도메인에 따라 다르게 표현될 수 있습니다. 따라서 추상화 시 해석자가 속한 도메인의 추상화 기준을 준수하는 것이 중요합니다.
이름 짓기는 추상화의 대표적인 행위로, 단순하면서도 고도의 추상적 사고를 요구하는 중요한 과정입니다. 이름을 짓는다는 것은 도메인의 문맥 안에서 이해되는 용어를 바탕으로, 구체적인 대상에서 핵심 개념만을 추출해 효과적으로 표현하는 것을 의미합니다.
// As-Is
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 10; j++) {
board[i][j] = "□";
}
}
String input = scanner.nextLine();
String input2 = scanner.nextLine();
// To-Be
// 별다른 의미가 없는 이름을 의도가 드러나도록 변경
for (int row = 0; row < 8; row++) {
for (int column = 0; column < 10; column++) {
board[row][column] = "□";
}
}
String cellInput = scanner.nextLine();
String userActionInput = scanner.nextLine();
잘 작성된 코드에서는 한 메서드가 반드시 하나의 주제만 다루어야 합니다. 메서드 이름을 통해 구체적인 내용을 추상화하고, 필수적인 정보와 생략할 정보를 구분하는 것이 중요합니다.
추상화된 이름으로 구체적인 내용을 유추하기 어렵다면, 해당 메서드가 두 가지 이상의 작업을 수행하고 있을 가능성이 큽니다. 이 경우, 의미를 분명히 담기 위해 더 작은 단위의 메서드로 분리해야 합니다. 메서드 추출은 코드 줄 수가 아닌 의미를 기준으로 이루어지기 때문에, 한줄의 메서드도 상관없습니다.

메서드명
파라미터
반환타입
// As-Is
// 두 가지 이상의 일을 하는 메서드
private static void checkIfAllCellIsOpened() {
boolean isAllOpened = true;
for (int row = 0; row < 8; row++) {
for (int col = 0; col < 10; col++) {
if (board[row][col].equals("□")) {
isAllOpened = false;
}
}
}
if (isAllOpened) {
gameStatus = 1;
}
}
// To-Be
// 한 가지 일을 집중적으로 확인하는 메서드
private static void checkIfGameIsOver() {
// 보드 내의 셀 들의 상태를 확인하는 메서드는 따로 분리한다.
boolean isAllOpened = isAllCellIsOpened();
if (isAllOpened) {
gameStatus = 1;
}
}
하나의 세계 안에서는 추상화 레벨이 동등해야 합니다.
“레몬에이드”라는 단어도 추상화 레벨에 따라 다른 방식으로 표현될 수 있습니다.
이처럼 중요한 정보를 얼마나 간추렸는지에 따라 추상화 레벨이 결정됩니다.
메서드를 추출할 때, 내부 세계(메서드 안)와 외부 세계(메서드 밖)로 나뉘며, 각 세계는 다른 추상화 레벨을 갖습니다.
// As-Is
// 너무 구체적인 내용을 if 안에 담지 않았는가?
public static void main(String[] args) {
showGameStartComments();
initializeGame();
showBoard();
...
// gameStatus == 1 이 무엇을 뜻하는가??
if (gameStatus == 1) {
System.out.println("지뢰를 모두 찾았습니다. GAME CLEAR!");
break;
}
}
// To-Be
// 추상화 레벨을 비슷하게
public static void main(String[] args) {
showGameStartComments();
initializeGame();
showBoard();
...
if (doesUserWinTheGame()) {
System.out.println("지뢰를 모두 찾았습니다. GAME CLEAR!");
break;
}
}
상수로 추출한다는 것은 이름을 부여하는 것입니다.
// As-Is
// 의미 파악이 어려운 매직 넘버
private static String[][] board = new String[8][10];
// To-Be
public static final int BOARD_ROW_SIZE = 8;
public static final int BOARD_COL_SIZE = 10;
private static final String[][] BOARD = new String[BOARD_ROW_SIZE][BOARD_COL_SIZE];
Readable Code: 읽기 좋은 코드를 작성하는 사고법 (박우빈)