[자바 코딩의 기술] 1. 코드 정리 생기초
22754 단어 자바 코딩의 기술독서refactoringJavaJava
3개월차 신입 비전공 개발자가 읽기 좋은 코드를 만들어보고자 공부하는 내용입니다. 부족하거나 새롭게 공부해보면 좋을 것 같은 추천, 글에서 발견된 문제에 대한 이야기는 언제든 환영합니다!
1. boolean 비교 하지 맙시다.
public class ExampleService {
private int a = 10;
private int b = 20;
public int escapeBooleanCompare() {
if (compareIntA(100) == true) {
return a;
} else {
return b;
}
}
private boolean compareIntA(int param) {
return param == a;
}
}
- 예시를 위해 막 만든 코드인데 조건문에서 값을 비교할 때 boolean 원시값은
==
비교하지 말자.
- 이러한 비교는 전혀 필요 없을 뿐더러 코드의 가독성과 이해를 떨어뜨림
- 수정사안
public int escapeBooleanCompare() {
if (compareIntA(100)) {
return a;
}
return b;
}
- else문을 써도 되지만 early return 방식을 적용도 같이 해봄 → if문도 깔끔해지고, 불필요한 else 문도 정리됨
2. 부정 피하기
- 조건문을 쓸 때 부정표현
if(!isTrue())
보다 if(isTrue())
처럼 !가 들어가는 부정은 사용하지 않는 게 좋다 → 긍정의 표현은 부정의 표현보다 코드의 이해도를 높이는데 도움이 됨
3. boolean 표현식 직접 반환
public class ExampleService {
private String name;
private int age;
public boolean checkUserInfo(String name, int age) {
if (age < 19 || Objects.isNull(name) || name.trim().isEmpty()) {
return false;
} else {
return true;
}
}
}
- 나이가 19 미만이면서 이름값이 null이거나 이름이 공백으로 들어오면 false를 리턴해주는 사용자 인증 코드
- 조건문에 뭔가 덕지덕지 들어가면서 코드 보기가 어려움. → 들여쓰기와 분기문이 들어가서 가독성이 떨어짐
public boolean checkUserInfo(String name, int age) {
return age > 19 && !Objects.isNull(name) && !name.trim().isEmpty();
}
- 조건문이 3개 이상 쓰일 경우 간소화를 하는 게 좋음 → 이 때 간소화 하는 조건문 덩어리들이 공통적으로 사용되는 부분이 있다면 메소드(함수)로 빼내는 게 좋음
public boolean checkUserInfo(String name, int age) {
boolean isValidAge = age > 19;
boolean isValidName = !Objects.isNull(name) && !name.trim().isEmpty();
return isValidAge && isValidName;
}
- x && y || z → (x && y) || z → 불 연산 시 &&이 || 보다 먼저 연산됨
4. 조건문에서 nullPointException 피하기
public void writeMessage(String message, Path location) {
if (Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
if (message.trim().isEmpty() || Objects.isNull(message)) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
}
- 자바 개발을 하다가 유효성(인수 검증)을 할 때 마주치는 가장 큰 문제 → nullPointexception
- 이러한 유효성 검사 시 순서가 가장 중요! → 위의 코드는 인수값이 사용하기 적합한 형태인지 먼저 확인한 후, null 여부를 확인함 → 이 때, 인수값이 사용되기 적합한 형태인지 확인하는 과정에서 nullPointException이 발생할 가능성이 높음.
- 유효성 검사의 올바른 순서는 null 체크 → 값의 사용 가능 여부(인수를 사용한 메소드면 좋음)
- 읽기 좋고 동작이 원활하게 되는 코드로 바꿔보자
public void writeMessage(String message, Path location) {
if (Objects.isNull(message) || message.trim().isEmpty()) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
if (Objects.isNull(location) || Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
}
- 먼저 파라미터의 순서에 따라 유효한 파라미터 체크를 함 → 가독성이 올라감(message의 유효성과 location 유효성 조건문의 위치 맞바꿈)
- null 체크 후 해당 값이 유효한지 여부에 대한 확인을 진행
- 그러나 항상 이러한 수준의 파라미터 유효성 검사는 하지 않아도 괜찮음
- 주로 public, protected, default에서 유효성 검사를 해줌
- private에서는 아예 null이 넘어오지 않도록 해주는 게 좋음
5. switch case 구문과 break
public void writeMessage(int a) {
String result;
switch (a) {
case 1 :
result = "one";
case 2 :
result = "two";
break;
case 3 :
result = "three";
break;
default:
result = "other";
break;
}
}
- switch case 구문은 정말 많은 버그를 일으키는 구문 중 하나
- 위의 예제 코드에서
case 1
블록에 break;
가 빠져있음 → 즉, 첫번째 case는 무조건 실패하고 두번째 case부터 나아가게 됨. → switch case가 버그로 악명 높은 이유 중 하나
- switch 구문은 관심사 분류가 어려울 수 있음
6. 중괄호 항상 사용하기
- 코드의 가독성을 높이기 위해서는 중괄호를 생략하기보다 사용하는 것이 좋음
public void writeMessage(int a) {
String result;
if (a == 1)
result = "one";
if (a == 2)
result = "two";
if (a == 3)
result = "three";
a++;
}
- 위의 코드처럼 if문이 한 줄로 끝나면 중괄호를 생략할 수 있음.
- 위의 예제 코드는 괄호를 안쓰고 잘못된 들여쓰기로 코드를 잘못 이해함 →
if(a == 3)
구문에 a++;가 연결되어 있는 것으로 보임
- 여담으로 if문의 중괄호는 예전부터 많은 논의의 대상이 됨 → 자신에게 맞는 걸 사용하자.
7. 코드 대칭 이루기
public void checkAuth() {
if (checkUserUnknown()) {
return;
} else if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 위의 코드를 보면 분기(if)구문들이 동일한 관심사로 분류를 하고 있지 않음
checkUserUnknown()
과 checkSupplier()
, checkConsumer()
는 서로 처리하는 관심사가 다름 → 사용자의 로그인 여부와 사용자의 페르조나(권한) 설정 2개의 관심사로 분리됨 → 얘를 분리해서 코드의 대칭성을 이루자.
public void checkAuth() {
if (checkUserUnknown()) {
return;
}
if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 로그인과 사용자 페르조나에 대해 분리를 함으로 코드의 대칭성 달성
Author And Source
이 문제에 관하여([자바 코딩의 기술] 1. 코드 정리 생기초), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@power0080/자바-코딩의-기술-1.-코드-정리-생기초
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class ExampleService {
private int a = 10;
private int b = 20;
public int escapeBooleanCompare() {
if (compareIntA(100) == true) {
return a;
} else {
return b;
}
}
private boolean compareIntA(int param) {
return param == a;
}
}
==
비교하지 말자.public int escapeBooleanCompare() {
if (compareIntA(100)) {
return a;
}
return b;
}
- 조건문을 쓸 때 부정표현
if(!isTrue())
보다if(isTrue())
처럼 !가 들어가는 부정은 사용하지 않는 게 좋다 → 긍정의 표현은 부정의 표현보다 코드의 이해도를 높이는데 도움이 됨
3. boolean 표현식 직접 반환
public class ExampleService {
private String name;
private int age;
public boolean checkUserInfo(String name, int age) {
if (age < 19 || Objects.isNull(name) || name.trim().isEmpty()) {
return false;
} else {
return true;
}
}
}
- 나이가 19 미만이면서 이름값이 null이거나 이름이 공백으로 들어오면 false를 리턴해주는 사용자 인증 코드
- 조건문에 뭔가 덕지덕지 들어가면서 코드 보기가 어려움. → 들여쓰기와 분기문이 들어가서 가독성이 떨어짐
public boolean checkUserInfo(String name, int age) {
return age > 19 && !Objects.isNull(name) && !name.trim().isEmpty();
}
- 조건문이 3개 이상 쓰일 경우 간소화를 하는 게 좋음 → 이 때 간소화 하는 조건문 덩어리들이 공통적으로 사용되는 부분이 있다면 메소드(함수)로 빼내는 게 좋음
public boolean checkUserInfo(String name, int age) {
boolean isValidAge = age > 19;
boolean isValidName = !Objects.isNull(name) && !name.trim().isEmpty();
return isValidAge && isValidName;
}
- x && y || z → (x && y) || z → 불 연산 시 &&이 || 보다 먼저 연산됨
4. 조건문에서 nullPointException 피하기
public void writeMessage(String message, Path location) {
if (Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
if (message.trim().isEmpty() || Objects.isNull(message)) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
}
- 자바 개발을 하다가 유효성(인수 검증)을 할 때 마주치는 가장 큰 문제 → nullPointexception
- 이러한 유효성 검사 시 순서가 가장 중요! → 위의 코드는 인수값이 사용하기 적합한 형태인지 먼저 확인한 후, null 여부를 확인함 → 이 때, 인수값이 사용되기 적합한 형태인지 확인하는 과정에서 nullPointException이 발생할 가능성이 높음.
- 유효성 검사의 올바른 순서는 null 체크 → 값의 사용 가능 여부(인수를 사용한 메소드면 좋음)
- 읽기 좋고 동작이 원활하게 되는 코드로 바꿔보자
public void writeMessage(String message, Path location) {
if (Objects.isNull(message) || message.trim().isEmpty()) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
if (Objects.isNull(location) || Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
}
- 먼저 파라미터의 순서에 따라 유효한 파라미터 체크를 함 → 가독성이 올라감(message의 유효성과 location 유효성 조건문의 위치 맞바꿈)
- null 체크 후 해당 값이 유효한지 여부에 대한 확인을 진행
- 그러나 항상 이러한 수준의 파라미터 유효성 검사는 하지 않아도 괜찮음
- 주로 public, protected, default에서 유효성 검사를 해줌
- private에서는 아예 null이 넘어오지 않도록 해주는 게 좋음
5. switch case 구문과 break
public void writeMessage(int a) {
String result;
switch (a) {
case 1 :
result = "one";
case 2 :
result = "two";
break;
case 3 :
result = "three";
break;
default:
result = "other";
break;
}
}
- switch case 구문은 정말 많은 버그를 일으키는 구문 중 하나
- 위의 예제 코드에서
case 1
블록에 break;
가 빠져있음 → 즉, 첫번째 case는 무조건 실패하고 두번째 case부터 나아가게 됨. → switch case가 버그로 악명 높은 이유 중 하나
- switch 구문은 관심사 분류가 어려울 수 있음
6. 중괄호 항상 사용하기
- 코드의 가독성을 높이기 위해서는 중괄호를 생략하기보다 사용하는 것이 좋음
public void writeMessage(int a) {
String result;
if (a == 1)
result = "one";
if (a == 2)
result = "two";
if (a == 3)
result = "three";
a++;
}
- 위의 코드처럼 if문이 한 줄로 끝나면 중괄호를 생략할 수 있음.
- 위의 예제 코드는 괄호를 안쓰고 잘못된 들여쓰기로 코드를 잘못 이해함 →
if(a == 3)
구문에 a++;가 연결되어 있는 것으로 보임
- 여담으로 if문의 중괄호는 예전부터 많은 논의의 대상이 됨 → 자신에게 맞는 걸 사용하자.
7. 코드 대칭 이루기
public void checkAuth() {
if (checkUserUnknown()) {
return;
} else if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 위의 코드를 보면 분기(if)구문들이 동일한 관심사로 분류를 하고 있지 않음
checkUserUnknown()
과 checkSupplier()
, checkConsumer()
는 서로 처리하는 관심사가 다름 → 사용자의 로그인 여부와 사용자의 페르조나(권한) 설정 2개의 관심사로 분리됨 → 얘를 분리해서 코드의 대칭성을 이루자.
public void checkAuth() {
if (checkUserUnknown()) {
return;
}
if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 로그인과 사용자 페르조나에 대해 분리를 함으로 코드의 대칭성 달성
Author And Source
이 문제에 관하여([자바 코딩의 기술] 1. 코드 정리 생기초), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@power0080/자바-코딩의-기술-1.-코드-정리-생기초
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public class ExampleService {
private String name;
private int age;
public boolean checkUserInfo(String name, int age) {
if (age < 19 || Objects.isNull(name) || name.trim().isEmpty()) {
return false;
} else {
return true;
}
}
}
public boolean checkUserInfo(String name, int age) {
return age > 19 && !Objects.isNull(name) && !name.trim().isEmpty();
}
public boolean checkUserInfo(String name, int age) {
boolean isValidAge = age > 19;
boolean isValidName = !Objects.isNull(name) && !name.trim().isEmpty();
return isValidAge && isValidName;
}
public void writeMessage(String message, Path location) {
if (Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
if (message.trim().isEmpty() || Objects.isNull(message)) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
}
- 자바 개발을 하다가 유효성(인수 검증)을 할 때 마주치는 가장 큰 문제 → nullPointexception
- 이러한 유효성 검사 시 순서가 가장 중요! → 위의 코드는 인수값이 사용하기 적합한 형태인지 먼저 확인한 후, null 여부를 확인함 → 이 때, 인수값이 사용되기 적합한 형태인지 확인하는 과정에서 nullPointException이 발생할 가능성이 높음.
- 유효성 검사의 올바른 순서는 null 체크 → 값의 사용 가능 여부(인수를 사용한 메소드면 좋음)
- 읽기 좋고 동작이 원활하게 되는 코드로 바꿔보자
public void writeMessage(String message, Path location) {
if (Objects.isNull(message) || message.trim().isEmpty()) {
throw new IllegalArgumentException("유효하지 않은 메시지입니다.");
}
if (Objects.isNull(location) || Files.isDirectory(location)) {
throw new IllegalArgumentException("유효하지 않은 경로입니다.");
}
}
- 먼저 파라미터의 순서에 따라 유효한 파라미터 체크를 함 → 가독성이 올라감(message의 유효성과 location 유효성 조건문의 위치 맞바꿈)
- null 체크 후 해당 값이 유효한지 여부에 대한 확인을 진행
- 그러나 항상 이러한 수준의 파라미터 유효성 검사는 하지 않아도 괜찮음
- 주로 public, protected, default에서 유효성 검사를 해줌
- private에서는 아예 null이 넘어오지 않도록 해주는 게 좋음
5. switch case 구문과 break
public void writeMessage(int a) {
String result;
switch (a) {
case 1 :
result = "one";
case 2 :
result = "two";
break;
case 3 :
result = "three";
break;
default:
result = "other";
break;
}
}
- switch case 구문은 정말 많은 버그를 일으키는 구문 중 하나
- 위의 예제 코드에서
case 1
블록에 break;
가 빠져있음 → 즉, 첫번째 case는 무조건 실패하고 두번째 case부터 나아가게 됨. → switch case가 버그로 악명 높은 이유 중 하나
- switch 구문은 관심사 분류가 어려울 수 있음
6. 중괄호 항상 사용하기
- 코드의 가독성을 높이기 위해서는 중괄호를 생략하기보다 사용하는 것이 좋음
public void writeMessage(int a) {
String result;
if (a == 1)
result = "one";
if (a == 2)
result = "two";
if (a == 3)
result = "three";
a++;
}
- 위의 코드처럼 if문이 한 줄로 끝나면 중괄호를 생략할 수 있음.
- 위의 예제 코드는 괄호를 안쓰고 잘못된 들여쓰기로 코드를 잘못 이해함 →
if(a == 3)
구문에 a++;가 연결되어 있는 것으로 보임
- 여담으로 if문의 중괄호는 예전부터 많은 논의의 대상이 됨 → 자신에게 맞는 걸 사용하자.
7. 코드 대칭 이루기
public void checkAuth() {
if (checkUserUnknown()) {
return;
} else if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 위의 코드를 보면 분기(if)구문들이 동일한 관심사로 분류를 하고 있지 않음
checkUserUnknown()
과 checkSupplier()
, checkConsumer()
는 서로 처리하는 관심사가 다름 → 사용자의 로그인 여부와 사용자의 페르조나(권한) 설정 2개의 관심사로 분리됨 → 얘를 분리해서 코드의 대칭성을 이루자.
public void checkAuth() {
if (checkUserUnknown()) {
return;
}
if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 로그인과 사용자 페르조나에 대해 분리를 함으로 코드의 대칭성 달성
Author And Source
이 문제에 관하여([자바 코딩의 기술] 1. 코드 정리 생기초), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@power0080/자바-코딩의-기술-1.-코드-정리-생기초
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public void writeMessage(int a) {
String result;
switch (a) {
case 1 :
result = "one";
case 2 :
result = "two";
break;
case 3 :
result = "three";
break;
default:
result = "other";
break;
}
}
case 1
블록에 break;
가 빠져있음 → 즉, 첫번째 case는 무조건 실패하고 두번째 case부터 나아가게 됨. → switch case가 버그로 악명 높은 이유 중 하나- 코드의 가독성을 높이기 위해서는 중괄호를 생략하기보다 사용하는 것이 좋음
public void writeMessage(int a) {
String result;
if (a == 1)
result = "one";
if (a == 2)
result = "two";
if (a == 3)
result = "three";
a++;
}
- 위의 코드처럼 if문이 한 줄로 끝나면 중괄호를 생략할 수 있음.
- 위의 예제 코드는 괄호를 안쓰고 잘못된 들여쓰기로 코드를 잘못 이해함 →
if(a == 3)
구문에 a++;가 연결되어 있는 것으로 보임 - 여담으로 if문의 중괄호는 예전부터 많은 논의의 대상이 됨 → 자신에게 맞는 걸 사용하자.
7. 코드 대칭 이루기
public void checkAuth() {
if (checkUserUnknown()) {
return;
} else if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 위의 코드를 보면 분기(if)구문들이 동일한 관심사로 분류를 하고 있지 않음
checkUserUnknown()
과 checkSupplier()
, checkConsumer()
는 서로 처리하는 관심사가 다름 → 사용자의 로그인 여부와 사용자의 페르조나(권한) 설정 2개의 관심사로 분리됨 → 얘를 분리해서 코드의 대칭성을 이루자.
public void checkAuth() {
if (checkUserUnknown()) {
return;
}
if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
- 로그인과 사용자 페르조나에 대해 분리를 함으로 코드의 대칭성 달성
Author And Source
이 문제에 관하여([자바 코딩의 기술] 1. 코드 정리 생기초), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@power0080/자바-코딩의-기술-1.-코드-정리-생기초
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
public void checkAuth() {
if (checkUserUnknown()) {
return;
} else if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
checkUserUnknown()
과 checkSupplier()
, checkConsumer()
는 서로 처리하는 관심사가 다름 → 사용자의 로그인 여부와 사용자의 페르조나(권한) 설정 2개의 관심사로 분리됨 → 얘를 분리해서 코드의 대칭성을 이루자.public void checkAuth() {
if (checkUserUnknown()) {
return;
}
if (checkSupplier()) {
System.out.println("반갑습니다. 판매자님");
} else if (checkConsumer()) {
System.out.println("반갑습니다. 고객님");
}
}
Author And Source
이 문제에 관하여([자바 코딩의 기술] 1. 코드 정리 생기초), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@power0080/자바-코딩의-기술-1.-코드-정리-생기초저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)