추상화
가독성 좋은 코드를 작성하는 첫번째 원리 추상과 구체를 이해하자
추상화는 최소 정보의 단위를 묶어서 어떻게 부를 것이냐에 관점이며, 컴퓨터 과학은 이러한 추상화 과정이 조화롭게 겹겹이 쌓여서 만들어진다
- 예를 들어보자면 1bit를 1byte, 1word 등 0과 1로만 이루어진 단위를 우리는 훨씬 더 큰 단위로 묶어서 부를 수 있고 그 단위로 인해 어플리케이션에서 제어할 수 있는 부분의 범위를 넓힌다. 
추상화 된 내용으로부터 구체적인 정보를 해석하지 못하는 경우
- 추상화 과정에서 중요한 정보를 부각 시키지는 못했을 때 - 상대적으로 덜 중요한 정보를 남기고 중요한 정보는 제거함 
 
- 해석자가 동일하게 공유하는 문맥이 없을 때 - 중요한 정보의 기준이 다를 수 있음 
- 도메인 영역 별 추상화 기준이 다를 수 있다는 걸 인지 해야함 
 
- 잘못된 추상화가 야기하는 사이드 이펙트는 생각보다 정말로 크다. 
- 적절한 추상화는 해당 도메인의 문맥 안에서 정말 중요한 핵심 개념만 남겨서 표현 하는 것 
📝 추상화의 가장 대표적인 행위
🗒️ 이름을 짓는다
👉 가장 단순하면서도 아주 중요한, 고도의 추상적 사고 행위
단수와 복수를 구분하기
- 끝에 -(e)s 를 붙여 어떤 데이터가 단수인지, 복수인지 나타내는 것이 읽는이에게 중요한 정보를 전달 할 수 있음 
이름 줄이지 않기
- 축약 할 때 효율성을 얻을 수 있으나 얻는 것에 비해 잃는 것이 큰 경우임 
- 자제하는 것이 좋긴 하나 관용어처럼 많은 사람들이 자주 사용하는 줄임말 정도는 허용함 
은어/방어 사용하지 않기
- 농담에서 파생된 용어나 일부 팀원, 현재 의 우리팀만 아는 용어 금지 - 새로운 사람이 팀에 합류 했을 때 이 용어를 단번에 이해 할 수 없는 단어는 사용 하지 말아야 함 
 
- 도메인 용어 사용하기 - 도메인 용어를 먼저 정의 하는 과정이 필요할 수 있음 - 예시) 매장 정보 → shop? store? 
 
 
좋은 코드를 보고 습득하기
- 비슷한 상황에서 자주 사용하는 단어, 개념 습득하기 - 예시) pool, candidate, threshold, etc 
 
Example use case:
- 👎 BAD! - int row = Character.getNumericValue(r) - 1; if (input2.equals("2")) { board[row][col] = "⚑"; boolean open = true; for (int i = 0; i < 8; i++) { for (int j = 0; j < 10; j++) { if (board[i][j].equals("□")) { open = false; } } } }
- 👍 GOOD! - int selectedRowIndex = Character.getNumericValue(cellInputRow) - 1; if (userActionInput.equals("2")) { board[selectedRowIndex][selectedColIndex] = "⚑"; boolean isAllOpend = true; for (int row = 0; row < 8; row++) { for (int col = 0; col < 10; col++) { if (board[row][col].equals("□")) { isAllOpend = false; } } } }
🙋♂️ 한 메서드의 주제는 반드시 하나다
🧰 메서드 선언(추출)
Example use case:
- 👎 BAD! - boolean isAllOpend = true; for (int row = 0; row < 8; row++) { for (int col = 0; col < 10; col++) { if (board[row][col].equals("□")) { isAllOpend = false; } } } if (isAllOpend) { gameStatus = 1; }
- 👍 GOOD! - private static void checkIfGameIsOver() { boolean isAllOpened = isAllCellOpened(); if (isAllOpened) { gameStatus = 1; } } private static boolean isAllCellOpened() { boolean isAllOpened = true; for (int row = 0; row < 8; row++) { for (int col = 0; col < 10; col++) { if (board[row][col].equals("□")) { isAllOpened = false; } } } return isAllOpened; }
💫 같은 패키지 내에서 추상화 레벨 맞추기
Example use case:
- 👎 BAD! - public static void main(String[] args) { showGameStartComments(); initializeGame(); showBoard(); ... if (gameStatus == 1) { // <- 추상화 레벨이 다른 구문 System.out.println("게임 클리어"); break; } }
- 👍 GOOD! - public static void main(String[] args) { showGameStartComments(); initializeGame(); showBoard(); ... if (doesUserWinTheGame()) { System.out.println("게임 클리어"); break; } }
🌇 매직 넘버, 매직 스트링을 상수로 추출하기
Example use case:
- 👎 BAD! - private static String[][] board = new String[8][10]; private static Integer[][] landMineCounts = new Integer[8][10]; private static boolean[][] landMines = new boolean[8][10]; private static int gameStatus = 0;
- 👍 GOOD! - 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]; private static final Integer[][] NEARBY_LAND_MINE_COUNTS = new Integer[BOARD_ROW_SIZE][BOARD_COL_SIZE]; private static final boolean[][] LAND_MINES = new boolean[BOARD_ROW_SIZE][BOARD_COL_SIZE]; public static final int LAND_MINE_COUNT = 10; public static final String FLAG_SIGN = "⚑"; public static final String LAND_MINE_SIGN = "☼"; public static final String CLOSED_CELL_SIGN = "□"; public static final String OPENED_CELL_SIGN = "■";
👉 예시처럼 자주 사용 되거나 의미를 갖고 있는 숫자나 문자를 뜻 함
Last updated