2022. 2. 2. 20:39ใBackend/๐ฟ Spring
๋ฌธ์ ์ธ์ง
ํ์ฌ์์ ๊ฐ๋ฐ์ค์ธ spring boot ํ๋ก์ ํธ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด์ Service layer ์ impl ํด๋์ interface ๊ฐ ๋์ ๊ณ์ ๋ฐํ์ต๋๋ค. ๋ณธ๋ ์๋ฐ์์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ๊ฐ์ฒด์งํฅ ํน์ง ์ค ํ๋์ธ ๋คํ์ฑ ์ ๋๋ค.
๋คํ์ฑ: ํ๋์ ์๋ฃํ์ ์ฌ๋ฌ๊ฐ์ง ๊ฐ์ฒด๋ฅผ ๋์ ํ์ฌ ๋ค์ํ ๊ฒฐ๊ณผ๋ฅผ ์ป์ด๋ด๋ ์ฑ์ง
๊ทธ๋ฐ๋ฐ ์์ ๊ทธ๋ฆผ์ ๋ณด๋ฉด ํ๋์ ์๋ฃํ(Interface ICSA2010Service)์ ๋ํ์ฌ ์ฌ๋ฌ๊ฐ์ง ๊ฐ์ฒด๊ฐ ์กด์ฌํ๋์? ์๋๋๋ค. ํด๋น ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ impl ํจํค์ง ํ์์ ํ๋ ๋ฐ์ ์กด์ฌํ์ง ์์ต๋๋ค. ์ฆ 1:N ๊ด๊ณ๊ฐ ์๋ 1:1์ ๊ด๊ณ๋ฅผ ํ์ฑํ๋ฉด์ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉ์ค์ธ ๊ฒ์ด์ฃ .
OCP ์ ์ ๊ฐํ ์ฝ๋์ด๊ธด ํ๋,, ์๋๋ฅผ ์๊ณ ์ฐ๋ ๊ฒ์ธ๊ฐ?
ํ์ง๋ง ์ค์ ๋ก ๋๋ถ๋ถ์ ํ๋ก์ ํธ์ ์ฝ๋๋ฅผ ๋ณด๋ฉด, interface ์ ๊ตฌํ์ฒด ํด๋์ค๋ 1:1๋ก ๊ตฌ์ฑ๋์ด, ์ค์ง์ ์ผ๋ก ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์๋ผ์ฐ๋ ์ํฉ์ด ๊ทธ๋ค์ง ์กด์ฌํ์ง ์์ต๋๋ค. ๋๋ถ๋ถ์ ํ๋ก์ ํธ, ๋น์ฅ ํ์ฌ ํ๋ก์ ํธ์์๋ ๊ด์ต์ ์ผ๋ก ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ์์ฑํ๋ ๊ฒ์ ์๋๊ฐ ์๊ฐ์ด ๋ค์์ต๋๋ค.
๊ด์ต์ ์ธ ์ถ์ํ์ ์ฅ์ ๊ณผ ๋จ์
์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ๋ถ๋ฆฌํ์ฌ ์ป์ ์ ์๋ ์ฅ์ ์ ๊ตฌํ์ฒด ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ํ์ฅํ๋๋ผ๋, ์ด๋ฅผ ํธ์ถํ๋ ํด๋ผ์ด์ธํธ ์ฝ๋์๋ ์ํฅ์ ์ฃผ์ง ์๋๋ค๋ ์ ์ ๋๋ค.
์ข ๋ ์์ธํ ์ค๋ช ํด๋ณด๊ฒ ์ต๋๋ค.
ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ํธ์ถ๋ถ๋ผ ๋ถ๋ฅธ๋ค๋ฉด, Service Layer ์ ์ฅ์์๋ ์๋น์ค ํด๋์ค๋ฅผ ํธ์ถํ๋ ์ปจํธ๋กค๋ฌ ํด๋์ค๊ฐ ํด๋ผ์ด์ธํธ ์ฝ๋์ผ ์ ์์ต๋๋ค. Service layer ์ ๊ตฌํ์ฒด ํด๋์ค๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ๊ต์ฒดํ๋ค๊ณ ๊ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค. (ex, AServiceImpl -> BServiceImpl)
ํด๋ผ์ด์ธํธ์ธ ์ปจํธ๋กค๋ฌ ์ ์ฅ์์๋ ์ด์ฐจํผ ์์กด์ฃผ์ ํ๋ ํ์ ์ IService ๋ผ๋ ์ธํฐํ์ด์ค๊ณ , ์ฌ๊ธฐ์ ์ ์๋ ์ถ์ ๋ฉ์๋๋ ๋ณํ์ง ์์ต๋๋ค.
์ธํฐํ์ด์ค
// Interface
public interface IService {
String test();
}
๊ตฌํ์ฒด
@Service
public class AServiceImpl implements IService {
@Override
public String test() {
return "AServiceImpl";
}
}
์ปจํธ๋กค๋ฌ
// Controller
@RequiredArgsConstructor
@RestController
public class SampleController {
private final IService service;
@GetMapping("/test")
public String test(){
return service.test();
}
}
์ ์์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ปจํธ๋กค๋ฌ๋ ํน์ ๊ตฌํ์ฒด๊ฐ ์๋ IService ํ์ ์ ์์กด ์ฃผ์ ๋ฐ๊ณ ์์ต๋๋ค. (๋ฌผ๋ก ํน์ ๊ตฌํ์ฒด์ธ AServiceImpl ์ ์์กด์ฃผ์ ๋ฐ์๋ ๊ด์ฐฎ์ต๋๋ค.)
์ด๋ ๊ฒ ๊ตฌํ์ฒด๊ฐ ์๋ ์ธํฐํ์ด์ค๋ฅผ ์์กด๋ฐ์ผ๋ฉด OCP ์์น์ ์งํฌ ์ ์์ต๋๋ค. ๋ฌด์จ ๋ป์ธ์ง ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ์์๋ก BServiceImpl ๊ตฌํ์ฒด๋ฅผ ์ถ๊ฐํด๋ณด๊ฒ ์ต๋๋ค.
๋ ๋ค๋ฅธ ๊ตฌํ์ฒด (BServiceImpl)
public class BServiceImpl implements IService {
@Override
public String test() {
return "BServiceImpl";
}
}
AServiceImpl ์ ๋ง์ฐฌ๊ฐ์ง๋ก IService์ ์ ์ธ๋ test() ๋ฉ์๋๋ฅผ ๊ตฌํํ๊ณ ์์ต๋๋ค. ์ด์ ์ด ํด๋์ค์ @Service ์ด๋ ธํ ์ด์ ์ ๋ถ์ด๋ฉด ์คํ๋ง ์ปจํ ์ด๋์ ์ํด SampleController ๋ก ์์กด์ฃผ์ ์ด ๋ฉ๋๋ค. ( AServiceImpl ์ @Service ์ด๋ ธํ ์ด์ ์ ์ ๊ฑฐํด์ฃผ์ด์ผ ํฉ๋๋ค.)
๋๋์ด ์ค์๋์?
IService ๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฒดํ ํ๋ ๊ตฌํ์ฒด๊ฐ์(AServiceImpl, BServiceImpl) ์ฐจ์ด๋ง ์์ ๋ฟ, ํด๋ผ์ด์ธํธ ์ฝ๋(์ปจํธ๋กค๋ฌ) ์
์ฅ์์๋ ๋ฌด์์ด ๋ณํ๋์ง ์ ํ ๋ชจ๋ฅด๋ ์ํ
์
๋๋ค. ์ฌ๊ธฐ์ ๋ชจ๋ฅด๋ ์ํ
๋ผ๋ ๊ฒ์, ServiceLayer ์ ๊ตฌํ์ฒด๊ฐ ๋ณ๊ฒฝ๋๋๋ผ๋ ํด๋ผ์ด์ธํธ ์ฝ๋๋ ์ ํ ์์ ํ ํ์๊ฐ ์๋ค๋ ์๋ฏธ์
๋๋ค. ์ง๊ธ์ ๋จ์ํ test() ๋ผ๋ ๋ฉ์๋์์ ๋ฌธ์์ด์ ์ถ๋ ฅํ๋ ๊ธฐ๋ฅ๋ฐ์ ์์ด ๊ฐํฅ์ด ์์ ์ ์์ต๋๋ค. ์ ๋ช
ํ ์์ ์ธ ์ ๋ฅ ํ ์ผ(%ํ ์ธ) ์ ์ก ํ ์ธ(1000์ ํ ์ธ) ์ ์๊ฐํด๋ด
์๋ค. ๋ง์ฝ ํ์ฌ๋ ์ ๋ฅ ํ ์ธ์ ์งํํ๋๋ผ๋, ๊ฐ์๊ธฐ ์ ์กํ ์ธ์ผ๋ก ์ ์ฑ
์ด ๋ณ๊ฒฝ๋๋ค๋ฉด, ์์ ์์ ์ฒ๋ผ ์๋น์ค๋ ์ด์ด์ ์ด๋
ธํ
์ด์
๋ง ๋ฐ๊ฟ์ฃผ๋ฉด ๊ฐ๋จํ๊ฒ ๋ณ๊ฒฝ๋ ์ ์ฑ
์ ์ฝ๋์ ๋ฐฐํฌํ ์ ์๊ฒ ๋ฉ๋๋ค.
↔ ๋ง์ฝ ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๊ฐ ๋ถ๋ฆฌ๋์ด ์์ง ์๋ค๋ฉด?
์ด ํฌ์คํ ์ ์ฐ๊ฒ ๋ ๊ณ๊ธฐ๋ ๋ณดํต ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๊ฐ์ ๊ด๊ณ๊ฐ 1:N ์ด ์๋ 1: 1 ๊ด๊ณ์ด๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ตฌํ์ฒด๊ฐ 2๊ฐ ์ด์์ด ์๋๋ผ๋ฉด ์ธํฐํ์ด์ค๊ฐ ํ์์์ง ์์๊น์? ๊ตณ์ด ์ธํฐํ์ด์ค ์์ด ์๋น์ค ์ฝ๋๋ง ์กด์ฌํด๋ ๊ด์ฐฎ์ง ์์๊น์?
์ด๋์ ๋๋ ๊ทธ๋ ๋ค๊ณ ์๊ฐํ์ง๋ง, ๊ทธ๋ผ์๋ ์ฌ์ ํ ์ธํฐํ์ด์ค๋ฅผ ๊ตณ์ด ์ ์ธํ๊ณ ๊ตฌํ์ฒด ์ฝ๋๋ฅผ ์์ฑํ ๊ฒ ๊ฐ์ต๋๋ค. ์ด์ ๋ ๊ธฐํ ์ ์ฑ ์ ์ ์ฐํ๊ฒ ๋์ํ๊ณ ์ถ๊ธฐ ๋๋ฌธ์ ๋๋ค. "์๋ฌด๋ฆฌ ๋ด๋ ์ด API ๋ ๊ธฐํ ์ ์ฑ ์ด ๋ณ๊ฒฝ๋ ์ผ์ด ์์๊บผ์ผ" ๋ผ๊ณ ๋จ์ธํ ์ ์๋ค๋ฉด ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ง ์๊ฒ ์ง๋ง, ์งง์ ๊ฒฝํ์ผ๋ก๋๋ง ๊ธฐํ ์ ์ฑ ์ ์ผ๋ง๋ ์ง ๋ณ๊ฒฝ๋ ์ ์๋ค๊ณ ๋๋ผ๊ฒ ๋์ต๋๋ค. ๋ํ ์์ ์์ ์ฝ๋๋ฅผ ํตํด OCP ๋ฅผ ์งํฌ ๋ ๊ฐ์ง ์ ์๋ ํธ๋ฆฌํจ๊ณผ ์์ ์ฑ ์ญ์ ๋์น ์ ์๋ ๋ถ๋ถ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ์ด๋๋ก ๊ด์ฐฎ์๊ฐ(feat. impl, I)
์ถ๊ฐ์ ์ผ๋ก ๋ค๋ฅธ ํฌ์คํ ์ ํตํด ์ธํฐํ์ด์ค์ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ๋ํด์๋ ์๊ฐํด ๋ณผ ์ ์์์ต๋๋ค.
Impl ์ ๊ตฌํ์ฒด์ ๋ถ์ด๋๊ฒ์ด ๊ด์ต์ ์ธ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ด ๋์ง๋ง ์ด๊ฒ์ด ํ๋นํ์ง ๊ณ ๋ฏผํด๋ณผ ํ์๊ฐ ์์ต๋๋ค.
๋ํ์ ์ผ๋ก ์๋ฐ Collection ์ List ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ArrayList, LinkedList ์์๋ impl ์ด๋ผ๋ ์ ๋ฏธ์ฌ๋ ์ฐพ์๋ณผ ์ ์์ต๋๋ค.
์๋๋ ์คํ์ค๋ฒํ๋ก์ฐ ์์ ๋ฐ์ทํ ๊ตฌ๋ฌธ์ ๋๋ค.
Look to the Java standard library itself. Do you see IList, ArrayListImpl, LinkedListImpl? No, you see List and ArrayList, and LinkedList. Here is a nice article about this exact question. Any of these silly prefix/suffix naming conventions all violate the DRY principle as well.
impl ์ ์ ๋ฏธ์ฌ๋ก ๋ถ์ด๋ ๊ฒ์ด DRY ์์น์ ์๋ฐฐํ๋ฉฐ ๋ถํ์ํ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ด๋ผ๊ณ ์ ๋ํ๊ฒ ๋นํํ๊ณ ์์ต๋๋ค. ์ ๊ธ์ ์ฝ๊ณ ๋๋
์์ผ๋ก interface ์ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค๋ ๋ค์ด๋ฐ์ ์ด๋ป๊ฒ ํด์ผํ ์ง ๋ค์๊ธ ์๊ฐํ๊ฒ ๋์ต๋๋ค.
ํ์ฌ ํ์ฌ์ ํ๋ก์ ํธ๋ถํฐ ์ด๋ฐ์์ ๋ค์ด๋ฐ ์ปจ๋ฒค์ ์ ๋ฐ๊พธ๊ณ ์ถ์ง๋ง, ์ด๋ฏธ ๊ด์ต์ผ๋ก ๊ตณ์ด์ง ์ฌํญ์ ๊ฐ์ธ์ด ๋ฐ๊พธ๋ ค๊ณ ํ๋ ๊ฒ์ ๋ค์ ๋ฌด๋ฆฌ๊ฐ ์๋ค๊ณ ๋ด ๋๋ค. ์์ผ๋ก์ ๊ฐ์ธ ํ๋ก์ ํธ๋ถํด ์ด๋ฐ ์ฌํญ์ ๋ํด ์ธ์งํ๋ฉด์ ๋ค์ด๋ฐ์ ์ ๊ฒฝ์จ์ผ๊ฒ ์ต๋๋ค.
reference
https://stackoverflow.com/questions/2814805/java-interfaces-implementation-naming-convention
'Backend > ๐ฟ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ฑ๊ธํค ์ปจํ ์ด๋ (0) | 2022.02.06 |
---|---|
์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น (0) | 2022.02.04 |
๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง (2) | 2022.01.26 |
ResponseEntity ๋์ Custom DTO ๋ฅผ ๋ฆฌํดํ ๋ ์ฃผ์ํ ์ (feat. @ResponseBody) (0) | 2021.12.22 |
Spring-boot, postgresql ์ฐ๋ ์ค ๋ฐ์ํ ์๋ฌ (0) | 2021.07.11 |