์ฝ๋ ๋ฆฌํฉํ ๋ง ๊ณผ์ ๋ฅผ ์ํํ๋ฉด์ ํ์ตํ ๋ด์ฉ์ ์ ๋ฆฌํด๋ณด์์ต๋๋ค.
๐ ํ์ตํ ๋ด์ฉ
1. Early return
์กฐ๊ฑด์ ๋ง์ง์๋ ๊ฒฝ์ฐ, ๋น ๋ฅด๊ฒ returnํ๊ฑฐ๋ ์์ธ๋ฅผ ๋ฐ์์์ผ ๋ถํ์ํ ๋ก์ง์ด ์คํ๋์ง ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
์ฑ๋ฅ ํฅ์, ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ด๋ ์ฅ์ ์ด ์๋ค.
ex) ํ์๊ฐ์ ์ ๋น๋ฐ๋ฒํธ๋ฅผ encode ํ email์ด ์ ํจํ์ง ์ฐพ๋๋ค๋ฉด, email์ด ์ ํจํ์ง ์์ ๊ฒฝ์ฐ ๋น๋ฐ๋ฒํธ๋ฅผ encodeํ ํ์๋ ๋ฌด์๋ฏธํ ๋์์ด ๋์ด๋ฒ๋ฆฐ๋ค. ๋๋ฌธ์, email์ด ์ ํจํ์ง ํ์ธํ๊ณ , ๋น๋ฐ๋ฒํธ๋ฅผ encode ํ ์ ์๋๋ก ์ฝ๋๋ฅผ ์ค๊ณํด์ผํ๋ค.
2. ๋ถํ์ํ if-else๋ฌธ ํผํ๊ธฐ
์ค์ฒฉ๋ if-else๋ฌธ์ ์ค์ฌ์ ์ฝ๋๋ฅผ ๊น๋ํ๊ฒ ์ ๋ฆฌํ๋ค.
์ด๋ฅผ Arrowhead ๋ฅผ Guard Clause ์คํ์ผ๋ก ๊ฐ์ ํ๋ค ๋ผ๊ณ ํํํ๋ค. (์ถ์ฒ: ์ต๋ช ์ ํํฐ๋)
์ ํ์ด์ด์ธ๊ฐ ํ๋๋..
๊ทธ๋ ์ต๋๋ค. ๋ช ํํ ์ฌ์ง!
์ฝ๋๋ก ๋ณด์๋ฉด ์๋์ ๊ฐ๋ค.
// Before๐คจ
if (!HttpStatus.OK.equals(response.getStatusCode())) {
throw new ServerException(...);
} else {
if (weatherArray == null || weatherArray.length == 0) {
throw new ServerException(...);
}
}
// After๐ค
if (!HttpStatus.OK.equals(response.getStatusCode())) {
throw new ServerException(...);
}
if (weatherArray == null || weatherArray.length == 0) {
throw new ServerException(...);
}
๊ตณ์ด ๋ค๋ฅธ ์กฐ๊ฑด๋ฌธ์ ๋น๊ตํ ๊ฑด๋ฐ if-else๋ฌธ์ ์ธ ํ์๊ฐ ์์๋ค.
์๋ฌด์๊ฐ ์์๋๋ฐ ์ญ์ ์๋ฌด์๊ฐ ์์ผ๋ฉด ์๋๋ค.
์ง๊ธ์ ์งง์ ์ฝ๋์ง๋ง ์ฝ๋๊ฐ ๊ธธ์ด์ง๋ฉด ๊ฐ๋ ์ฑ์ ํ์ฐํ๊ฒ ์ฐจ์ด๊ฐ ๋ ๊ฒ ๊ฐ๋ค.
3. DTO Validation์ผ๋ก ์ฑ ์ ์ด์ ํ๊ธฐ
๊ธฐ์กด์๋ Service ๊ณ์ธต์์ if๋ฌธ์ผ๋ก ์ ํจ์ฑ์ ๊ฒ์ฌํ์ง๋ง, DTO์์ ์ด๋ ธํ ์ด์ ๊ธฐ๋ฐ Validation์ผ๋ก ๊ฒ์ฆํ๋ค.
์๋น์ค์๋ ๊ฒ์ฆ๋ ๊ฐ๋ง ๋ค์ด์ค๋ฏ๋ก ๋ก์ง์ด ๊ฐ๊ฒฐํด์ง๋ค.
์ฌ์ฉ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ org.springframework.boot:spring-boot-starter-validation
๋์ผํ ์ด๋ฆ์ด ์์ผ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊น์ง ์์ํด์ ๊ณต๋ถํด์ผํ๋ค...
4. N+1 ๋ฌธ์
โ๏ธ N+1 ๋ฌธ์ ๋?
N๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์กฐํํ ๋, ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ฐ ๋ก๋ฉ(LAZY)์ผ๋ก ๊ฐ์ ธ์ค๋ฉฐ ์ถ๊ฐ๋ก N๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๋ ํ์์ด๋ค.
์์๋ฅผ ๋ค์๋ฉด,
1. ๊ฒ์๊ธ 10๊ฐ ์กฐํ → ์ฟผ๋ฆฌ 1๋ฒ ์คํ (SELECT * FROM posts)
2. ๊ฐ ๊ฒ์๊ธ์ ์์ฑ์(User)๋ฅผ ์กฐํ → ๊ฒ์๊ธ ์๋งํผ ์ฟผ๋ฆฌ ์คํ๋จ (N๋ฒ)
SELECT * FROM users WHERE id = ?
...์ด๊ฒ 10๋ฒ ์คํ๋จ ๐จ
์ฆ ์ด 1+N ๋ฒ์ ์ฟผ๋ฆฌ๊ฐ ์คํ๋๋ ๊ฒ์ด๋ค...
์ฒ์์๋ ์ ์ฒด๋ฅผ ๋ถ๋ฌ์ค๋ 1๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ถ๊ฐ๋ ๊ฒ์ด๋ผ ์๊ฐํ๋๋ฐ, ์ฐ๊ด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ์ํ N๋ฒ์ด ์ถ๊ฐ๋ก ๋ถ๋ฌ์ค๊ฒ ๋๋๊ฒ์ด์๋ค. 1์ด ์ถ๊ฐ์ธ ์ค ์๊ณ ํฐ ๋ฌธ์ ๊ฐ ์๋๋ผ๊ณ ์๊ฐํ๋๋ฐ N์ด ์ถ๊ฐ๋ผ๋.. ์์ฃผ ํฐ ๋ฌธ์ ์๋ค.
๐ ๋จ์
์ฟผ๋ฆฌ๊ฐ ๋๋ฌด ๋ง์ด ์คํ๋์ด์ ์ฑ๋ฅ์ด ๋จ์ด์ง๊ณ , ์๋ฒ ๋ถํ๊ฐ ์ปค์ง๋ค.
ํนํ ๊ฒ์๊ธ ์๊ฐ ๋ง์์ง๋ฉด N์ด ์์ฒญ ์ปค์ง๊ฒ ๋๋ค → ๊ทธ๋งํผ ๋๋ ค์ง๋ค.
๐ ํด๊ฒฐ๋ฒ
โ๏ธ fetch join
@Query("SELECT p FROM Post p JOIN FETCH p.user")
List<Post> findAllWithUser();
๊ฒ์๊ธ(p)๊ณผ ์์ฑ์(p.user)๋ฅผ ํ ๋ฒ์ ์ฟผ๋ฆฌ๋ก ๋ฌถ์ด์ ๊ฐ์ ธ์จ๋ค.
โ๏ธ @EntityGraph
@EntityGraph(attributePaths = {"user"})
List<Post> findAll();
์ฟผ๋ฆฌ ๋ฉ์๋์ ์ฐ๊ด ์ํฐํฐ๋ฅผ ํจ๊ป ๊ฐ์ ธ์ค๋ผ๊ณ ๋ช ์ํ๋ ๋ฐฉ๋ฒ์ด๋ค.
fetch join๊ณผ ์ ์ฌํ ํจ๊ณผ์ง๋ง ์ข ๋ ๋ช ํํ๋ค.
๐ ๋ฐ์ ์์ธ
์ฐ๊ด๊ด๊ณ๊ฐ ์ง์ฐ๋ก๋ฉ์ผ๋ก ์ด๋ฃจ์ด์ ธ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ฒ์๊ธ ๋จผ์ ๋ถ๋ฌ์ค๊ณ , ์์ฑ์๋ ๋์ค์ ํ์ํ ๋ ๋ ๋ถ๋ฌ์ฌ๊ฒ์~ ๋ผ๊ณ ์ค์ ํด์ N๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ์ถ๊ฐ๋ก ์คํ๋๋ ๊ฒ์ด์๋ค.
์์งํ๊ฒ ๋งํ์๋ฉด.. ์์ง ์ง์ฐ๋ก๋ฉ์ด ๋ญ์ง ๋ชจ๋ฅด๊ฒ ๊ณ ๊ทธ๋์ fetch join, @EntityGraph ์ด๋ป๊ฒ ์ฐ๋์ง ๋ชจ๋ฅด๊ฒ ๋ค. ์ด๊ฑด ๋ณ๋์ ๊ฒ์๊ธ๋ก ์ ๋ฆฌ๋ฅผ ํ๋ฉด์ ๊ณต๋ถ๋ฅผ ํด์ผํ๋ค ใ .ใ
ํ์คํ ์๊ฒ๋ ํ์ค ์์ฝ์ N+1 ๋ฌธ์ ์ ํด๊ฒฐ๋ฒ์ ์ฐ๊ด๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ๊ฐ์ ธ์์ ์ฟผ๋ฆฌ์๋ฅผ ์ค์ฌ์ฃผ๋ ๊ฒ์ด๋ค.
5. ํ ์คํธ์ฝ๋
ํ๋๋ ๋ชจ๋ฅด๊ฒ ๋ค. ๊ณผ์ ์์ ๋ณด์ฌ์ค ์คํจ ์ด์ ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋ฉ์๋ ํ๋ผ๋ฏธํฐ ์์๋ฅผ ์๋ชป ๋ฃ์
- Service ๊ณ์ธต์์๋ A๋ผ๋ ์์ธ ์ฒ๋ฆฌ๋ฅผ ํ๋๋ฐ, ํ ์คํธ์์๋ B๋ฅผ ๊ธฐ๋ํ๋ค.
- todo.getUser()๊ฐ null์ธ ์ํ์์ getId()๋ฅผ ํธ์ถํ์ฌ, NPE๊ฐ ๋ฐ์ํ๋ค.
์์ธ์ข ๋ฅ๋ ๋ ๊ณต๋ถํด์ผํ๋ค. ์ด๋ฒ ๊ณผ์ ์์ ๊ณต๋ถํ ์์ธ๋ ์๋ 2๊ฐ..
- InvalidRequestException: ๊ฐ๋ฐ์๊ฐ ์ง์ ์๋ชป๋ ์์ฒญ์ด๋ผ๊ณ ํ๋จํด์ ์๋์ ์ผ๋ก ๋์ง๋ ์์ธ
- NullPointerException: null์ธ ๊ฐ์ฒด์ ์ ๊ทผํ์ ๋ ์๋ฐ๊ฐ ์๋์ผ๋ก ํฐ๋จ๋ฆฌ๋ ์์ธ, ์ฌ์ ์ null ์ฒดํฌ ํ์
์ ๋ ํ ์คํธ์ ํตํฉ ํ ์คํธ
- ์ ๋ ํ ์คํธ: ๋ฉ์๋ ํ๋๋ง ๋ ๋ฆฝ์ ์ผ๋ก ํ ์คํธ
- ํตํฉ ํ ์คํธ: ์ฌ๋ฌ ์ปดํฌ๋ํธ๊ฐ ์ฐ๊ฒฐ๋ ์ํ(ex: ์ปจํธ๋กค๋ฌ ์ ์ฒด)
ํ ์คํธ ์์ฑ ๊ตฌ์กฐ๋ given-when-then ํจํด์ ๋ฐ๋ฅด๋ค. (์ค๋น-์คํ-๊ฒ์ฆ)
@ExtendWith, @InjectMocks ์ด๋ฐ ์ฒ์๋ณด๋ ์ด๋ ธํ ์ด์ ๋ค.. ์ธ์ ๋ณต์ต๊ณผ ์ค์ต์ด ํ์ํ๋ค๐ญ
โ๏ธ ๋๋์
๋ฆฌํฉํ ๋ง ์ด๋๊ฑธ ์ฒ์ ๊ฒฝํํด๋ณด์๋ค.
ํด๋ฆฐ์ฝ๋, N+1 ๋ฌธ์ , ํ ์คํธ ์ฝ๋์ ๋ํ ๊ณต๋ถ๊ฐ ํ์ํ๋ค.
'๋ด์ผ๋ฐฐ์์บ ํ > ๋ณธ์บ ํ ๊ณผ์ ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ฐฐ๋ฌ ์ดํ๋ฆฌ์ผ์ด์ ์์์์ฑ ํ๋ก์ ํธ ํ๊ณ (3) | 2025.04.29 |
---|---|
[์ผ์ ๊ด๋ฆฌ์ฑ Develop-3] ์ผ์ ๊ด๋ฆฌ์ฑ Develop ๊ณผ์ ํ๊ณ (1) | 2025.04.04 |
[์ผ์ ๊ด๋ฆฌ์ฑ Develop-2] ์ผ์ ๊ด๋ฆฌ์ฑ Develop ํธ๋ฌ๋ธ ์ํ (0) | 2025.04.03 |
[์ผ์ ๊ด๋ฆฌ์ฑ Develop-1] ERD ๋ฐ API ๋ช ์ธ์ ์์ฑ (0) | 2025.04.02 |
[์ผ์ ๊ด๋ฆฌ์ฑ ๋ง๋ค๊ธฐ-3] ์ผ์ ๊ด๋ฆฌ์ฑ ๊ณผ์ ํ๊ณ (1) | 2025.03.26 |