https://start.spring.io/ ์์ ์์ ํ์ผ ์์ฑ(dependency X)
์๋ฐ 21๋ก ํ๋ฉด ์ค๋ฅ๋๋๊น 17๋ก~!!
setting - gradle - gradle prijects - build and run ์ธํ ๋ฆฌ์ ์ด๋ก ๋ฐ๊พธ๊ธฐ(gradleํตํด์ ์คํํ๋ฉด ๋๋ฆผ)
๋จ์ถํค ํ์ธ
setting - keymap
์ค๋ฌด์์๋ ๊ทธ๋ฅ ํด์๋งต๋์ `concurrentHashMap`์ ์ฌ์ฉํ๋ค (๋์์ฑ ์ด์)
์ธํ ๋ฆฌ์ ์ด ๋จ์ถํค command shft enter (๋ฌธ์ฅ ์๋์์ฑ ๋จ์ถํค)
command + option + V (์ฐธ์กฐ๋ณ์ ์๋์์ฑ)
option + Enter (์ํฌํธ ๋ฑ ์ค๋ฅ๋ ๊ณณ์ผ๋ก ์ด๋)
command + shifh + T (ํ ์คํธ ์ฝ๋ ์์ฑํ๊ธฐ)
command + E + Enter (์ด์ ์ฐฝ์ผ๋ก ๋์๊ฐ๊ธฐ)
command + E ํ์คํ ๋ฆฌ ์ฐฝ
๊ตฌํ์ฒด๊ฐ ํ๋์ธ ๊ฒฝ์ฐ ์ฃผ๋ก ํด๋์ค ์ด๋ฆ์ Impl์ ๋ถ์
ํ ์คํธ ์ฝ๋๋ ์ฑ๊ณตํ๋ ๊ฒ๋ ์ค์ํ์ง๋ง ์คํจํ๋ ์ผ์ด์ค๋ฅผ ํ์ธํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํ๋ค(์์ธ ํฐ์ง๋ ๊ฒ ํ์ธํ๊ธฐ)
`Assertions`
ํจํค์ง: org.assertj.core.api.Assertions
// ํ ์ธ์ ์ฑ
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
// ์ ์ฝ๋๋ ํด๋ผ์ด์ธํธ(ํด๋น ํด๋์ค)๊ฐ ๊ตฌํ์ฒด์ ์ง์ ์์กดํ๊ณ ์์(DIP ์๋ฐ, OCP ์๋ฐ)
// ํ ์ธ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋๋ฉด ์ค์ ์ฝ๋๊ฐ ๋ณ๊ฒฝ๋จ
์ ์ฝ๋๋ ๊ฒ๋ณด๊ธฐ์๋ง ์ธํฐํ์ด์ค์ ์์กดํ๊ณ ์๋ ๋ชจ์์ ํ ๋ฟ ์ค์ ์์ฑ๋๋ ๊ฐ์ฒด๋ฅผ ์ง์ ์ ์ผ๋ก ์ ์ธํ๊ณ ์์ผ๋ฏ๋ก `FixDiscountPolicy`๋ `RateDiscountPolicy`๋ฅผ ์์กดํ๊ณ ์๋ค.(๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์กดํ๊ณ ์์)
ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝํ๋ ค๋ฉด ํด๋ผ์ด์ธํธ`OrderServiceImpl`์ ์ฝ๋๋ฅผ ๊ณ ์ณ์ผํ๋ค. OCP/DIP๋ฅผ ์๋ฐํ๊ณ ์๋ค.
๊ฐ์๋ฆฐ ์๋์ฐจ์์ ์ ๊ธฐ ์๋์ฐจ๋ก ๋ฐ๋์๋ค๊ณ ๋ผ์ด์ผ์ค๋ฅผ ์๋ก ๋ฐ์ผํ๋ ๊ฒฉ์ด๋ค.
์ด๋ป๊ฒ ํด๊ฒฐํ ์ ์์๊น?
๐ฃ๏ธ ์์กด ๊ด๊ณ๋ฅผ ๋์จํ๊ฒ ํ๊ธฐ ์ํด ์์ฑ์์์ ๋งค๊ฐ๋ณ์๋ก `discountPolicy`๋ฅผ ๋ฐ๋ ๋ฑ์ ๋ฐฉ์์ผ๋ก ๋ฐ์ผ๋ก๋ถํฐ `DiscountPolicy`๋ฅผ ๊ตฌํํ ๊ฐ์ฒด๋ฅผ ๋ฐ์์์ ๋ฃ์ด์ฃผ๋ ๋ฐฉ์์ ์ด์ฉํ๋ฉด ์ด๋จ๊น์ฉ
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์๋ ๊ตฌํ์ฒด๊ฐ ์๋ ์ธํฐํ์ด์ค๋ง์ ์์กดํด์ผํ๋ค.
private DiscountPolicy discountPolicy;
๊ทธ๋ฐ๋ฐ ์ด ์ํ๋ก ์คํํ๋ฉด `NullpointException`์ด ๋ฐ์ํ๋ค. (๋น์ฐํจ.. null์)
ํด๋ผ์ด์ธํธ๋ ์ธํฐํ์ด์ค๋ง์ผ๋ก๋ ์๋ฌด๊ฒ๋ ์คํํ ์ ์๋ค. (๋น์ฐํจ...... ์ธํฐํ์ด์ค์)
๊ทธ๋ฌ๋ฉด ์ด ๋ฌธ์ ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ ๊น? -> ๋๊ตฐ๊ฐ๊ฐ ํด๋ผ์ด์ธํธ์ธ `OrderServiceImpl`์ `DiscountPolicy`์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํด์ค์ผํ๋ค!
๊ฐ์ฒด ์ฃผ์ ๋ง์ ๋ด๋นํ๋ ํด๋์ค๋ฅผ ์๋ก ์์ฑํ๋ค. -> `AppConfig`
๋ฐ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ์ฃผ์ ํด์ค๋ค.
๊ณต์ฐ์์ ๋ฐฐ์ฐ๋ ์ฐ๊ธฐ๋ง์ ๋ด๋นํ๊ณ , ๋ฐฐ์ฐ ์ญ์ธ๋ ๊ธฐํ์๊ฐ ํ๋ค.
// public class OrderServiceImpl implements OrderService
private final MemberRepository memberRepository;
// ํ ์ธ์ ์ฑ
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
// ์ ์ฝ๋๋ ํด๋ผ์ด์ธํธ(ํด๋น ํด๋์ค)๊ฐ ๊ตฌํ์ฒด์ ์ง์ ์์กดํ๊ณ ์์(DIP ์๋ฐ, OCP ์๋ฐ)
private DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
.
.
.
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
.
.
.
public class AppConfig {
public MemberService memberService(){
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService() {
return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
}
}
`AppConfig`๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ๋์์ ํ์ํ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
`AppConfig`์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ํด๋ผ์ด์ธํธ`OrderServiceImpl`์๊ฒ ์์ฑ์๋ฅผ ํตํด ์ฃผ์ (Injection)ํด์ฃผ๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ํด๋์ค๋ ๊ตฌ์ฒด์ ์ธ ํด๋์ค์ ๋ํ ์ ๋ณด๋ฅผ ์ ํ ๋ชจ๋ฅด๊ณ ์๋ค.
ํด๋ผ์ด์ธํธ์ ์ ์ฅ์์ ๋ณด๋ฉด ๋ง์น ์์กด ๊ด๊ณ๋ฅผ ์ธ๋ถ์์ ์ฃผ์ ํด์ฃผ๋ ๊ฒ ๊ฐ๋ค๊ณ ํด์ DI(Dependency Injection: ์์กด๊ด๊ณ ์ฃผ์ (์์กด์ฑ ์ฃผ์ ))์ด๋ผ๊ณ ํ๋ค.
public class MemberApp {
public static void main(String[] args) {
AppConfig appConfig = new AppConfig();
// MemberService memberService = new MemberServiceImpl();
MemberService memberService = appConfig.memberService();
.
.
.
public class OrderApp {
public static void main(String[] args) {
AppConfig appConfig = new AppConfig();
MemberService memberService = appConfig.memberService();
OrderService orderService = appConfig.orderService();
.
.
.
Main์์๋ `AppConfig`๋ฅผ ์์ฑํ์ฌ ์์กด๊ด๊ณ๋ฅผ ์ฃผ์ ํด์ค๋ค. ๋ ๋ค ๊ตฌ์ฒด ํด๋์ค์ ์์กดํ์ง ์๊ณ ์ธํฐํ์ด์ค์๋ง ์์กดํ๋ค. (๊ตฌ์ฒด ํด๋์ค๊ฐ ๋ฌด์์ธ์ง ์ ํ ๋ชจ๋ฅด๊ณ ์๋ค -> ์์ ํ ํ์๊ฐ ์๋ค)
`@BeforeEach`
ํ ์คํธ ํด๋์ค์์ ๋ชจ๋ ํ ์คํธ๋ง๋ค ์ ์ฉํด์ผํ ๋ ํด๋น ๋ฉ์๋(์ํ๋์ด์ผ ํ๋ ๋ฉ์๋) ์์ ๋ถ์ด๋ ์ ๋ํ ์ด์
public class MemberServiceTest {
MemberService memberService;
@BeforeEach
public void beforeEach(){
AppConfig appConfig = new AppConfig();
memberService = appConfig.memberService();
}
@Test
void join() {
.
.
.
`@BeforeEach`๋๋ถ์ ํ ์คํธ ์ผ์ด์ค๋ง๋ค ๋๊ฐ์ ์ฝ๋๋ฅผ ์์ฑํ ํ์๊ฐ ์์ด์ง
์ด์ ํด๋ผ์ด์ธํธ `OrderServiceImpl`์ ๊ตฌ์ฒด ํด๋์ค๊ฐ ๋ฌด์์ธ์ง ์ ๋ณด๋ฅผ ์ ํ์ ์์ด ์์ ์ ์ญํ ์ ์ถฉ์คํ ์ ์๊ฒ ๋์๋ค.
๊ทธ๋ฐ๋ฐ `AppConfig`๊ฐ ์ด๋ค ์ญํ ์ ๊ฐ์ง๊ณ ์๋์ง ํ ๋์ ์ธ์งํ๊ธฐ ์ด๋ ต๋ค. ๊ทธ๋์ ๋ฉ์๋ ์ด๋ฆ๋ง ๋ด๋ ์ด๋ค ์ผ์ ํ๋์ง ์ ์ ์๋๋ก ๋ฆฌํฉํฐ๋ง ํด์ฃผ๊ธฐ๋ก ํ๋ค.
1. ์ญํ ๊ณผ ๊ตฌํ ๋ถ๋ฆฌ
2. ์ญํ ์ด ์ ๋๋ฌ๋๋๋ก ์์ฑ
3. ์ค๋ณต์ ์ ๊ฑฐํจ (new ์ด์ฉ๊ตฌ ๊ตฌ๊ตฌ์ ์ ์ฝ๋๋ฅผ ๋ฉ์๋๋ก ๋นผ๋ธ๋ค)
public class AppConfig {
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
public DiscountPolicy discountPolicy(){
return new FixDiscountPolicy();
}
}
๋ฉ์๋ ์ด๋ฆ๋ง ๋ด๋ ์ด๋ค ์ผ์ ํ๋์ง ์ ์ ์๊ฒ ๋์๋ค. (๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์ฑํด์ ๋ฆฌํดํ๋ ์ญํ )
๋ฉค๋ฒ ์๋น์ค, ๋ฆฌํฌ์งํ ๋ฆฌ, ์ค๋์๋น์ค, ํ ์ธ์ ์ฑ ์ด ๋ฐ๋์ด๋ ํด๋น ํด๋์ค๋ง ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
์๋ฅผ ๋ค์ด ๋ณด์. ๊ธฐํ์๊ฐ ๊ธฐ์กด์ ์ ์ก ํ ์ธ ์ ์ฑ `FixDiscountPolicy`์์ ์ ๋ฅ ํ ์ธ ์ ์ฑ `RateDiscountPolicy`๋ก ๋ณ๊ฒฝํ์๊ณ ์๊ตฌํ๋ค. ๊ทธ๋ฌ๋ฉด ์ด๋ ๋ถ๋ถ์ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํด์ผํ๊ฒ ๋๊ฐ?
๐ฃ๏ธ `AppConfig`์ ๋งจ ๋ง์ง๋ง์ค์ธ `discountPolicy()` ๋ฉ์๋์ ๋ฆฌํด์ ์์ ํฉ๋๋น
ใด ใ ใ ๋ง์
public DiscountPolicy discountPolicy(){
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
ํ ์ธ ์ ์ฑ ์ด ๋จ ํ ์ค์ ์ฝ๋ ์์ ์ผ๋ก ์์ฝ๊ฒ ๋ณ๊ฒฝ๋์๋ค.
๊ตฌ์ฑ ์์ญ์ ์ ์ฑ ์ด ๋ณ๊ฒฝ๋๋ฉด ๋น์ฐํ ๋ณ๊ฒฝ๋๋ค! ๊ตฌ์ฑ ์ญํ ์ ๋ด๋นํ๋ `AppConfig`๋ฅผ ๊ณต์ฐ ๊ธฐํ์๋ผ๊ณ ์๊ฐํ์. DI๋ฅผ ์ ์ค์ ํด์ฃผ๋ฉด ํด๋ผ์ด์ธํธ์ ์ ํ ์๋์ง ์๊ณ ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ ํ๊ณ ํ์ฅํ ์ ์๋ค. ์ฌ์ฉ ์์ญ์ ์ด๋ค ์ฝ๋๋ ๋ณ๊ฒฝ๋์ง ์์๋ค.
OCP(ํ์ฅ์๋ ์ด๋ ค์๊ณ ๋ณ๊ฒฝ์๋ ๋ซํ์๋ค)์ DIP(์ถ์ํ์ ์์กด)๊ฐ ์์ฃผ ์ ์ง์ผ์ง๊ณ ์๋ค.
1. SRP "ํ ํด๋์ค๋ ํ๋์ ์ฑ ์๋ง ๊ฐ์ ธ์ผ ํ๋ค." ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ.
2. OCP "์ํํธ์จ์ด ์์๋ ํ์ฅ์๋ ์ด๋ ค์์ผ๋ ๋ณ๊ฒฝ์๋ ๋ซํ์์ด์ผ ํ๋ค." - ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฌ์ฉ ์์ญ๊ณผ ๊ตฌ์ฑ ์์ญ์ผ๋ก ๋๋์ด ์ ์ฑ ์ด ๋ณ๊ฒฝ๋์ด ์์ ์ด ๋ฐ์ํ ๊ฒฝ์ฐ ๊ตฌ์ฑ ์์ญ๋ง ์์ ํ๋๋ก ์ฝ๋๋ฅผ ์์ฑํจ.
3. DIP "๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์กดํ์ง ์๊ณ ์ถ์ํ์ ์์กดํด์ผ ํ๋ค." - ์์กด์ฑ ์ฃผ์ (DI)๋ ์ด ์์น์ ๋ฐ๋ฅด๋ ๋ฐฉ๋ฒ ์ค ํ๋์.
์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋์ ๊ณต์ฐ์ผ๋ก ์๊ฐํด๋ณด์.
๋ฐฐ์ฐ๋ ์ฐ๊ธฐ๋ง ํ๊ณ , ๊ธฐํ์๋ ๊ธฐํ์ ํ๊ณ , ๊ฐ๋ ์ ๊ฐ๋ ๋ง ํ๋ค. ์ฑ ์์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค.
`AppConfig`๋ ์ ์ฒด ๋์ ๋ฐฉ์์ ๊ตฌ์ฑํ๊ธฐ ์ํด ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฐ๊ฒฐํ๋ ์ฑ ์๋ง์ ๊ฐ์ง๊ณ ์๋ค.
ํด๋ผ์ด์ธํธ ๊ฐ์ฒด๋ ์์ ์ ์ญํ ์ ์คํํ๋ ๊ฒ์ ์ง์คํ ์ ์๋ค. ๊ถํ์ด ์ค์ด๋ค์ด ์ฑ ์์ด ๋ช ํํด์ก๋ค.
์ ์ด์ ์ญ์ : IoC(Inversion of Control)
์ด์ ์๋ ํด๋ผ์ด์ธํธ ๊ตฌํ ๊ฐ์ฒด `OrderServiceImpl`์ด ์ค์ค๋ก ํ์ํ ์๋ฒ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฐ๊ฒฐํ๊ณ ์คํํ๋ค.(ํ๋ก๊ทธ๋จ์ ์ ์ด ํ๋ฆ์ ์ค์ค๋ก ์กฐ์ข ํจ)
`AppConfig`๊ฐ ๋ฑ์ฅํ ์ดํ๋ก ๊ตฌํ ๊ฐ์ฒด๋ ์์ ์ ๋ก์ง์ ์คํํ๋ ์ญํ ๋ง ๋ด๋นํ๋ค. ์ฆ, ํด๋ผ์ด์ธํธ ๊ตฌํ ๊ฐ์ฒด๋ ์ค์ค๋ก ํ๋ก๊ทธ๋จ์ด ์ด๋ป๊ฒ ํ๋ฌ๊ฐ๋์ง ์ ํ ๋ชจ๋ฅด๊ณ ์๋ค. ํ๋ก๊ทธ๋จ์ ๋ํ ์ ์ด ํ๋ฆ์ `AppConfig`๊ฐ ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด๋ค.
์ด๋ ๋ฏ ์ ์ด์ ํ๋ฆ์ ์ค์ค๋ก ๊ฐ์ง๊ณ ์๋ ๊ฒ์ด ์๋๋ผ ์ธ๋ถ์์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ ์ด์ ์ญ์ (IoC)๋ผ๊ณ ํ๋ค.
๋ด๊ฐ ์์ฑํ ์ฝ๋๋ฅผ ๋์ ์ ์ดํ๊ณ ๋์ ์คํํ๋ฉด ํ๋ ์์ํฌ(์ ์ด์ ์ญ์ )
๋ด๊ฐ ์์ฑํ ์ฝ๋๋ฅผ ๋ด๊ฐ ์ ์ดํ๊ณ ์คํํ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์ ์ ์ธ ํด๋์ค ์์กด ๊ด๊ณ: ํด๋์ค๊ฐ ์ฌ์ฉํ๋ import ํด๋์ค๋ง ๋ด๋ ์์กด ๊ด๊ณ๋ฅผ ์ฝ๊ฒ ํ๋จํ ์ ์๋ค. (์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ์ง ์๊ณ ๋ ์์กด ๊ด๊ณ๋ฅผ ๋ถ์ํ ์ ์๋ค.) `OrderServiceImpl` ๊ตฌ์ฒด ํด๋์ค๋ `DiscountPolicy` ์ธํฐํ์ด์ค์ ์์กดํ๋ค.
์์กด ๊ด๊ณ ์ฃผ์ (์์กด์ฑ ์ฃผ์ ): DI(Dependency Injection)
`OrderServiceImpl` ๊ตฌ์ฒด ํด๋์ค๋ `DiscountPolicy` ์ธํฐํ์ด์ค์ ์์กดํ๋ค. ๊ทธ๋ฌ๋ ์ค์ ์ฃผ์ ๋๋ ๊ฒ์ด ์ด๋ค ๊ฐ์ฒด์ธ์ง๋ ์ ์ ์๋ค.(ํด๋ผ์ด์ธํธ๊ฐ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์ ํ ๋ชจ๋ฅธ๋ค.) ์ด๋ฅผ ๋์ ์ธ ํด๋์ค ์์กด ๊ด๊ณ๋ผ๊ณ ํ๋ค. ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์์ ์ ์ธ๋ถ์์ ์ค์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํด๋ผ์ด์ธํธ์๊ฒ ์ ๋ฌํด์ฃผ์ด ์์กด๊ด๊ณ๊ฐ ์คํ๋๋ ๊ฒ์ ์์กด ๊ด๊ณ ์ฃผ์ ์ด๋ผ๊ณ ํ๋ค.
`AppConfig`์ฒ๋ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ฉด์ ์์กด ๊ด๊ณ๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ์ IoC ์ปจํ ์ด๋ ๋๋ DI ์ปจํ ์ด๋๋ผ๊ณ ํ๋ค.
'Java > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] ์คํ๋ง์ ์ ์ (3) - Spring MVC (0) | 2024.01.01 |
---|---|
[Spring] ์คํ๋ง์ ์ ์ (2) - ์์ฒญ๊ณผ ์๋ต (0) | 2023.12.31 |
[Spring] ์คํ๋ง์ ์ ์ (1) ์ด๊ธฐ ์ค์ (0) | 2023.12.30 |
[Spring] ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ธฐ๋ณธํธ (3) (0) | 2023.12.28 |
[Spring] ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ธฐ๋ณธํธ (2) (0) | 2023.12.27 |