์ง๊ธ๊น์ง ์์ฑํ ์ฝ๋ ์ค๋ช
ํ์๊ฐ์ ์ ํ๊ณ , ์กฐํํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
๋ฌผ๊ฑด์ ๊ตฌ์ ํ ๋ ํ ์ธ ์ ์ฑ ์ ๋ง๋ค๊ณ ์ถ์ด์ ๊ณ ์ ๋ ํ ์ธ๊ธ์ก์ ํ ์ธํด์ฃผ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
๊ทธ๋ฐ๋ฐ ๊ธฐ์ ์์ ๊ณ ์ ๋ ํ ์ธ๊ธ์ก์ด ์๋๋ผ ํผ์ผํธ๋ก ํ ์ธํด์ฃผ๊ณ ์ถ๋ค๊ณ ํ๋ฉด ์ฝ๋๋ฅผ ๋ฐ๊ฟ์ผํ๋ค.
package hello.core.discount;
import hello.core.member.Grade;
import hello.core.member.Member;
public class RateDiscountPolicy implements DiscountPolicy {
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if (member.getGrade() == Grade.VIP) {
return price * discountPercent / 100;
} else{
return 0;
}
}
}
JAVA๋ฅผ ๋ฐฐ์ฐ๋ฉด์ enum์ ์ธ ์ผ์ด ์์ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋๋ฐ ์ด๋ฒ ์ค์ต์ ํ๋ฉด์ enum๋ฅผ ์์ฃผ ์ฌ์ฉ ํ๊ฒ ๋ ๊ฒ ๊ฐ๋ค๊ณ ๋๊ผ๋ค..์จ๋ !
10ํผ์ผํธ๋ฅผ ํ ์ธํด์ฃผ๋ ์ ์ฑ ์ฝ๋๋ฅผ ์์ฑํ๊ณ , ํด๋ผ์ด์ธํธ์์ ๋ณ๊ฒฝํด์ฃผ๋ฉด ๋๋ค.
๊ทผ๋ฐ ๊ฐ์ฒด์งํฅ 5๊ฐ์ง ์์น์ค์์ OCP๋ฅผ ์๋ฐํ๊ณ ์๋ค.
์ด ์ ํฌ์คํ ์ ๋ณด๋ฉด OCP ์์น์ ํ์ฅ์๋ ์ด๋ ค์์ผ๋ ๋ณ๊ฒฝ์๋ ๋ซํ์์ด์ผ ํ๋ค๊ณ ํ๋ค.
๊ทผ๋ฐ ์์ ๊ฐ์ ์ฝ๋์์๋ ํด๋ผ์ด์ธํธ ์ฝ๋๊น์ง ๋ณ๊ฒฝํด์ผํ๋ ๊ฒฝ์ฐ๊ฐ ์๊ธด๋ค.
์ด์ฒ๋ผ ๊ณ ์ ๊ธ์ก์์ ๋น์จ๊ธ์ก์ผ๋ก ๋ฐ๋๋ ์ธํฐํ์ด์ค๋ง๋ค ์์กดํ๊ณ ์๋ ์ค ์์๋๋ฐ, ๊ตฌ์ฒดํด๋์ค๋ ์์กดํ๊ณ ์๊ณ , ์ ์ฑ ์ ๋ฐ๊ฟ ๋ ํด๋ผ์ด์ธํธ ์ฝ๋๊น์ง ๋ณ๊ฒฝํด์ผํ๋ค. ๐ DIP, OCP์๋ฐ
ํด๋ผ์ด์ธํธ๊ฐ ์ธํฐํ์ด์ค๋ง ์์กดํ๊ธฐ ์ํด์๋ ๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํด์ผํ๋ค!
AppConfig ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ๊ตฌํ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์ฐ๊ฒฐํด์คฌ๋ค.
package hello.core;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
public class AppConfig {
public MemberService memberService() {
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl(new MemoryMemberRepository(), new RateDiscountPolicy());
}
}
AppConfig๋ฅผ ์ด์ฉํด์ ๊ตฌํ๊ฐ์ฒด๋ฅผ ์์ฑํด๊ณ , ๊ฐ์ฒด ์ธ์คํด์ค ์ฐธ์กฐ๋ฅผ ์์ฑ์๋ฅผ ํตํด์ ์ฃผ์ ํด์ค๋ค.
package hello.core.member;
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository;
//์ถ์ํ์๋ง ์์กดํจ (DIP ์งํด)
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
์์ฑ์๋ฅผ ๋ง๋ค์ด์ ์ฐ๊ฒฐํด์ผ์ฃผ๋ฉด DIP๋ฅผ ์งํฌ ์ ์๊ฒ ๋๋ค.
์ฃผ๋ฌธ์๋น์ค๋ ๋๊ฐ์ด ๋ฐ๊ฟ์ฃผ์๋ค.
๊ทธ๋ฌ๋ฉด AppConfig๊ฐ ๋ชจ๋ ์์กด๊ด๊ณ๋ฅผ ๋๋งก์์ ํ๊ณ , MemberServiceImpl๋ ์คํ๋ง ํ๋ฉด ๋๋ค.
๊ทธ๋ผ ์ด config๋ฅผ ์คํํ๊ธฐ ์ํด์ ๋ฉ์ธ ํด๋์ค๋ ์์ ํด์ค์ผํ๋ค.
AppConfig appConfig = new AppConfig();
MemberService memberService = appConfig.memberService();
OrderService orderService = appConfig.orderService();
์ด๋ ๊ฒ config ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ membersService์ orderService๊ฐ์ฒด๋ฅผ ์ฐ๊ฒฐ์์ผ์ฃผ๋ฉด ๋๋ค!
package hello.core.member;
import hello.core.AppConfig;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class MemberServiceTest {
MemberService memberService;
@BeforeEach
// ์คํํ๊ธฐ ์ ์ ๋ฌด์กฐ๊ฑด ๋์ํด์ผ๋จ
public void beforeEach(){
AppConfig appConfig = new AppConfig();
memberService = appConfig.memberService();
}
@Test
void join(){
//given
Member member = new Member(1L, "memberA", Grade.VIP);
//when
memberService.join(member);
Member findMember = memberService.findMember(1L);
//then
Assertions.assertThat(member).isEqualTo(findMember);
}
}
ํ ์คํธ ์ฝ๋์๋ DIP๋ฅผ ์ํด์ ๊ฐ์ฒด ์ ์ธ๋ง ํด์ฃผ๊ณ ํ ์คํธ ์คํํ๊ธฐ ์ ์ Config๋ ๊ฐ์ฒด๋ ์ฐ๊ฒฐ์์ผ์ฃผ๋ฉด ๋๋ค!
์คํํ๋ฉด ์ ์ด๋ ๋๊ฐ์ ์คํ๊ฒฐ๊ณผ๊ฐ ๋์จ๋คโชโฟโช
์์ AppConfig์์ ์ค๋ณต๋ ๊ฐ์ ์ ๊ฑฐํ๊ณ ์ข ๋ ๊น๋ํ๊ฒ ๋ง๋ค์ด์ค๋ค.
์ญํ ๊ณผ ์ ํ๋ฆฌ์ผ์ด์ ๊ตฌ์ฑ์ ํ๋์ ๋ณผ ์ ์๊ฒ ๋ง๋ค์ด์ฃผ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๊ฑธ ์คํ๋ง๊ธฐ๋ฐ์ผ๋ก ๋ณ๊ฒฝํ๋ค!!
package hello.core;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.discount.RateDiscountPolicy;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.member.MemoryMemberRepository;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration //AppConfig์ ์ค์ ์ ๊ตฌ์ฑํ๋ค๋ ๋ป
public class AppConfig {
@Bean //์คํ๋ง ๋น์ ๋ฑ๋ก
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemoryMemberRepository memberRepository() {
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
@Bean
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
}
//์ญํ ์ด ๋๋ฌ๋๊ฒ ๋ณ๊ฒฝ
}
public class MemberApp {
public static void main(String[] args) {
//AppConfig appConfig = new AppConfig();
//MemberService memberService = appConfig.memberService();
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
Member member = new Member(1L, "memberA", Grade.VIP );
memberService.join(member);
Member findMember = memberService.findMember(1L);
System.out.println("new member = " + member.getName());
System.out.println("find Member = " + findMember.getName());
}
}
1. ApplicationContext = ์คํ๋ง์ปจํ ์ด๋๋ผ๊ณ ํ๋ค.
2. .getBean("ํด๋์ค ์ด๋ฆ", ํด๋์ค)๋ฅผ ์์ฑํ๋ฉด ํด๋์ค์ด๋ฆ์ ํด๋นํ๋ ์คํ๋ง ๊ฐ์ฒด๋ฅผ ์ฐพ์ ์ ์๋ค.
๐ ํ์ํ ์คํ๋ง ๋น์ ์๋ฌด๋๋ ์ฐพ์์ ์ฌ์ฉ ๊ฐ๋ฅ
โ [์ค๋ ๋ฐฐ์ด ๊ฒ ์ค ๊ฐ์ฅ ์ค์ํ ๊ฒ]
โ DIP์ OCP๋ฅผ ์ค์ํด์ผ๋จ
โ ์ง์ ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ ๋์ค์ ๋ณ๊ฒฝ์ฌํญ์ด ์์ ๋ ํด๋ผ์ด์ธํธ๊น์ง ๋ณ๊ฒฝํด์ผํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์๊ธด๋ค.
ํด๋ผ์ด์ธํธ ๋ฟ๋ง ์๋๋ผ ๊ทธ ๊ฐ์ฒด ๊ด๋ จ๋ ์ฝ๋๋ ๋ชจ๋ ๋ณ๊ฒฝํด์ค์ผ๋จ.
๊ฐ์ฅ ์ค์ํ๊ฒ๋ ์์น์ ์๋ฐ๋๋ค.
โ ๋คํ์ฑ๋ง ๊ฐ์ง๊ณ ๋ ํด๊ฒฐ์ด ์๋๊ธฐ ๋๋ฌธ์ ์ญํ ์ ๋ถ๋ฆฌ์์ผ์ค์ผํ๋ค.
โ AppConfig๋ฅผ ๋ง๋ค์ด์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์คํ๊น์ง ์์ผ์ค๋ค.
ํด๋ผ์ด์ธํธ ๊ตฌํ ๊ฐ์ฒด๊ฐ ์ค์ค๋ก ํ์ํ ์๋ฒ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ํ๋ก๊ทธ๋จ์ ์ด์ ์์ ์ ์ญํ ์๋ง ์ถฉ์คํ๋ฉด ๋จ
โ์ด์ฒ๋ผ ์ง์ ์ ์ด ํ๋ฆ์ ์ ์ดํ๋ ๊ฒ์ด ์๋๋ผ ์ธ๋ถ์์ ๊ด๋ฆฌํด์ฃผ๋ ๊ฒ์ ์ ์ด์ ์ญ์ (IoC)๋ผ๊ณ ํ๋ค.
โ์ฌ๊ธฐ์ Config ์ฒ๋ผ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ฉด์ ์์กด๊ด๊ณ๋ฅผ ์ฐ๊ฒฐํด์ฃผ๋ ๊ฒ์ IoC์ปจํ ์ด๋ ๋๋ DI์ปจํ ์ด๋๋ผ๊ณ ํจ
โ์คํ๋ง๊ธฐ๋ฐ์ผ๋ก ๋ณ๊ฒฝํ๋ ค๋ฉด AppConfig์ ์ค์ ์ ๊ตฌ์ฑํ๋ค๋ ๋ป์ธ @Configuration์ ๋ถ์ฌ์ฃผ๊ณ @Bean์ ๋ฑ๋กํ๋ฉด ๊ทธ ๋ฉ์๋๋ ๋ชจ๋ ์คํ๋ง๋น์ผ๋ก ๋ฑ๋ก๋๋ค. ์คํ๋ง๋น์ผ๋ก ๋ฑ๋ก๋๋ฉด ํ์ํ ๋ ์ธ์ ๋ ๊บผ๋ด ์ธ ์ ์๋ค.
โ๊ทธ๋ฌ๋ฉด ๋ณ๊ฒฝ์ฌํญ์ด ์์ ๋ AppConfig๋ง ์์ ํ๋ฉด ๋ค๋ฅธ ๊ฒ์ ๋ณ๊ฒฝํ์ง ์์๋ ์ ์ฉ์ด ๋๋ค.
์ถ์ฒ : ์ธํ๋ฐ ๊น์ํ๋ ๊ฐ์ - https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard
'Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring ๊ธฐ๋ณธ [ ์ฑ๊ธํค/์คํ๋ง์ปจํ ์ด๋] (0) | 2021.07.11 |
---|---|
Spring ๊ธฐ๋ณธ [์คํ๋ง๋น ์กฐํ] (0) | 2021.07.09 |
H2 DB ๋ค์ด๋ก๋ [์ค์น / ์๋ฒ ์คํ] (0) | 2021.06.27 |
Spring [ ํ์ ๋ฑ๋ก/์กฐํ/ํ์ ๊ด๋ฆฌ ์์ /์คํ๋ง] (0) | 2021.06.25 |
Spring [์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ / ํ์ ์๋น์ค ์คํ๋ง๋น ๋ฑ๋ก] (0) | 2021.06.25 |