ํด๋น ํฌ์คํ ์ ๊น์ํ๋์ ์ธํ๋ฐ ๊ฐ์(์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ)๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ
"์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋์ ๊ณต์ฐ์ด๋ผ๊ณ ํ์ ๋, ์คํ๋ง์ ๊ณต์ฐ์ ๋ฐฐ์ญ(์ญํ )์ ๋ง๋ ๋ฐฐ์ฐ(๊ตฌํ์ฒด)๋ฅผ ์ญ์ธํ๋ ๊ณต์ฐ ๊ธฐํ์๋ผ๊ณ ํ ์ ์๋ค."
์๋ ์ฝ๋๋ ๊ฐ์ฒด ์งํฅ ์ค๊ณ ์์น ์ค OCP์ DIP๋ฅผ ์๋ฐํ๊ณ ์๋ค.
public class OrderServiceImpl implements OrderService {
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
...
}
OCP ์๋ฐ
- OCP : ์ํํธ์จ์ด ์์๋ ํ์ฅ์๋ ์ด๋ ค์์ผ๋ ๋ณ๊ฒฝ์๋ ๋ซํ์์ด์ผ ํ๋ค.
- ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝํ๋ ค๋ฉด ํด๋ผ์ด์ธํธ ์ฝ๋๊น์ง ๋ณ๊ฒฝํด์ผํ๋ค.
DIP ์๋ฐ
- DIP : ํ๋ก๊ทธ๋๋จธ๋ ์ถ์ํ์ ์์กดํด์ผ์ง, ๊ตฌ์ฒดํ์ ์์กดํ๋ฉด ์๋๋ค.
- ํด๋ผ์ด์ธํธ(OrderServiceImpl)๊ฐ ์ธํฐํ์ด์ค(DiscountPolicy) ๋ฟ๋ง ์๋๋ผ ๊ตฌํ์ฒด(FixDiscountPolicy, RateDiscountPolicy)๊น์ง ์์กดํ๊ณ ์๋ค.
ํด๊ฒฐ๋ฐฉ์
- ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ํด๋ผ์ด์ธํธ์ธ OrderServiceImpl์ DiscountPolicy์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋์ ์์ฑํ๊ณ ์ฃผ์ ํด์ฃผ์ด์ผ ํ๋ค.
- ์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด Orderservice์ ์ญํ ์ ๋งก์ OrderServiceImpl์ MemberRepository์ DiscountPolicy๋ผ๋ ์ญํ ๋ง์ ์๊ณ ์๊ณ , ๊ทธ ๊ตฌํ์ฒด๋ ์์ง ๋ชปํ๋ค.
- ๊ฐ๊ฐ์ ์ญํ ์ ๊ตฌํ์ฒด๋ AppConfig๊ฐ ์ฃผ์ ์ ํตํด ์ ๊ณตํ๋ค.
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
...
}
public class AppConfig {
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
private MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
...
}
์ฌ์ฉ ์์ญ๊ณผ ๊ตฌ์ฑ ์์ญ
- AppConfig์ ๋ฑ์ฅ์ผ๋ก ์ ํ๋ฆฌ์ผ์ด์ ์ด ํฌ๊ฒ ์ฌ์ฉ ์์ญ๊ณผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ตฌ์ฑํ๋ ๊ตฌ์ฑ ์์ญ์ผ๋ก ๋ถ๋ฆฌ๋์๋ค.
- ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝํด๋ ๊ตฌ์ฑ ์์ญ๋ง ์ํฅ์ ๋ฐ๊ณ , ์ฌ์ฉ ์์ญ์ ์ ํ ์ํฅ์ ๋ฐ์ง ์๋๋ค.
- ๋ฐ๋ผ์ ํด๋ผ์ด์ธํธ ๊ฐ์ฒด๋ ์์ ์ ์ญํ ์ ์คํํ๋ ๊ฒ์๋ง ์ง์คํ ์ ์๋ค. -> ์ฑ ์์ด ๋ช ํํด์ง๋ค(SRP)

์ ๋ฆฌ
- ๋คํ์ฑ๋ง์ผ๋ก๋ ์ข์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ 5๊ฐ์ง ์์น(SOLID) ์ค OCP์ DIP๋ฅผ ์งํค์ง ๋ชปํ๋ค.
- ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด AppConfig๊ฐ ๋ฑ์ฅํ๊ณ , ์ด๋ฅผ ํตํด ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌ์ํด์ผ๋ก์ OCP์ DIP(๋๋ถ์ด SRP)๋ฅผ ์งํฌ ์ ์๋ค.
IOC, DI, ๊ทธ๋ฆฌ๊ณ ์ปจํ ์ด๋
์ ์ด์ ์ญ์ IoC
ํ๋ก๊ทธ๋จ์ ์ ์ด ํ๋ฆ์ ์ง์ ์ ์ดํ๋ ๊ฒ์ด ์๋๋ผ ์ธ๋ถ์์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ ์ด์ ์ญ์ ์ด๋ผ ํ๋ค.
ํ๋ ์์ํฌ vs ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ํ๋ ์์ํฌ๊ฐ ๋ด๊ฐ ์์ฑํ ์ฝ๋๋ฅด ์ ์ดํ๊ณ , ๋์ ์คํํ๋ฉด ๊ทธ๊ฒ์ ํ๋ ์์ํฌ๊ฐ ๋ง๋ค. (JUnit)
- ๋ฐ๋ฉด์ ๋ด๊ฐ ์์ฑํ ์ฝ๋๊ฐ ์ง์ ์ ์ด์ ํ๋ฆ์ ๋ด๋นํ๋ค๋ฉด ๊ทธ๊ฒ์ ํ๋ ์์ํฌ๊ฐ ์๋๋ผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค.
์์กด๊ด๊ณ ์ฃผ์ DI
์์กด๊ด๊ณ๋ ์ ์ ์ธ ํด๋์ค ์์กด ๊ด๊ณ์, ์คํ ์์ ์ ๊ฒฐ์ ๋๋ ๋์ ์ธ ๊ฐ์ฒด(์ธ์คํด์ค) ์์กด ๊ด๊ณ ๋์ ๋ถ๋ฆฌํด์ ์๊ฐํด์ผ ํ๋ค.
- ์ ์ ์ธ ํด๋์ค ์์กด๊ด๊ณ
- ํด๋์ค๊ฐ ์ฌ์ฉํ๋ import ์ฝ๋๋ง ๋ณด๊ณ ์์กด๊ด๊ณ๋ฅผ ์ฝ๊ฒ ํ๋จํ ์ ์๋ค. (์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ์ง ์์๋ ๋ถ์ํ ์ ์๋ค.)
- ํด๋์ค ์์กด๊ด๊ณ ๋ง์ผ๋ก๋ ์ค์ ์ด๋ค ๊ฐ์ฒด๊ฐ ํด๋ผ์ด์ธํธ ๊ฐ์ฒด์ ์ฃผ์ ๋ ์ง ์ ์ ์๋ค.

- ๋์ ์ธ ๊ฐ์ฒด(์ธ์คํด์ค) ์์กด ๊ด๊ณ
- ์ ํ๋ฆฌ์ผ์ด์ ์คํ ์์ ์ ์ค์ ์์ฑ๋ ๊ฐ์ฒด ์ธ์คํด์ค์ ์ฐธ์กฐ๊ฐ ์ฐ๊ฒฐ๋ ์์กด ๊ด๊ณ๋ค.

์ ํ๋ฆฌ์ผ์ด์ ์คํ ์์ ์ ์ธ๋ถ์์ ์ค์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ํด๋ผ์ด์ธํธ์ ์ ๋ฌํด์ ํด๋ผ์ด์ธํธ์ ์๋ฒ์ ์ค์ ์์กด๊ด๊ณ๊ฐ ์ฐ๊ฒฐ ๋๋ ๊ฒ์ ์์กด๊ด๊ณ ์ฃผ์ ์ด๋ผ ํ๋ค.
์์กด๊ด๊ณ ์ฃผ์ ์ ์ฌ์ฉํ๋ฉด ์ ์ ์ธ ํด๋์ค ์์กด๊ด๊ณ๋ฅผ ๋ณ๊ฒฝํ์ง ์๊ณ , ๋์ ์ธ ๊ฐ์ฒด ์ธ์คํด์ค ์์กด๊ด๊ณ๋ฅผ ์ฝ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ค. -> ์คํ ์์ ์ ๊ตฌํ์ฒด๋ฅผ ๊ฒฐ์ ํ ์ ์๋ค.
DI ์ปจํ ์ด๋(IoC ์ปจํ ์ด๋)
์์ ์์ ์์์ AppConfig ์ฒ๋ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ฉด์ ์์กด๊ด๊ณ๋ฅผ ์ฐ๊ฒฐํด ์ฃผ๋ ๊ฒ์ DI ์ปจํ ์ด๋(๋๋ Ioc ์ปจํ ์ด๋)๋ผ ํ๋ค.
์คํ๋ง ์ปจํ ์ด๋
- ApplicationContext๋ฅผ ์คํ๋ง ์ปจํ ์ด๋๋ผ ํ๋ค.
- ๊ธฐ์กด์๋ ๊ฐ๋ฐ์๊ฐ AppConfig๋ฅผ ์ฌ์ฉํด์ ์ง์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ DI๋ฅผ ํ์ง๋ง, ์ด์ ๋ถํฐ๋ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด์ ์ฌ์ฉํ๋ค.
public class OrderApp {
public static void main(String[] args) {
// AppConfig๋ฅผ ์ง์ ์์ฑ ๋ฐ ์ฌ์ฉ
// AppConfig appConfig = new AppConfig();
// MemberService memberService = appConfig.memberService();
// OrderService orderService = appConfig.orderService();
// ์คํ๋ง ์ปจํ
์ด๋ ์ฌ์ฉ
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
OrderService orderService = applicationContext.getBean("orderService", OrderService.class);
...
}
}
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public OrderService orderService() {
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public DiscountPolicy discountPolicy() {
return new RateDiscountPolicy();
}
}
// ์คํ๋ง ์คํ ์ ๋ก๊ทธ
23:59:27.548 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'memberService'
23:59:27.562 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'memberRepository'
23:59:27.563 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'orderService'
23:59:27.564 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'discountPolicy'
'Spring > [์ธํ๋ฐ] ์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ปดํฌ๋ํธ ์ค์บ (0) | 2021.05.19 |
---|---|
๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง (0) | 2021.04.15 |