๐ [Spring] ๐ป ์คํ๋ง ํต์ฌ์๋ฆฌ - 2. ์คํ๋ง ํต์ฌ ์๋ฆฌ ์ดํด 1,2
๐ป [Spring] ์คํ๋ง ํต์ฌ์๋ฆฌ - ์คํ๋ง ํต์ฌ ์๋ฆฌ ์ดํด 1,2
์๋
ํ์ธ์. ๐
์คํ๋ง์ผ๋ก ์ฌ๋ฌ ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํ์๋๋ฐ
๋ฌธ๋ ์คํ๋ง ์์ฒด ํต์ฌ ์๋ฆฌ์ ๋ํ ๋ณต์ต์ด ํ๊ณ ์ถ์์ต๋๋ค.
๊ทธ๋์ ๊น์ํ๋์ ์คํ๋ง ํต์ฌ์๋ฆฌ ๊ฐ์๋ฅผ ๋ค์ผ๋ฉฐ
์คํ๋ง์ ์ ์ฌ์ฉํด์ผํ๋์ง์
์คํ๋ง ํต์ฌ์๋ฆฌ์ ๋ํด ํ์ตํ ๋ด์ฉ์
๋๋ค.
๋๋ฒ์งธ ์๊ฐ์
๋๋ค.
์ง์ ์์ ์๋ฐ๋ง์ ์ด์ฉํด ๊ฐ์ฒด ์งํฅ ์๋ฆฌ๋ฅผ ์ ์ฉํด ์์ ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํด๋ณด์์ต๋๋ค.
์ง์ ์ค์ตํด๋ณด๋ฉฐ ๋๋ ์ฃผ์ ๋ด์ฉ๋ค์ ์์ฃผ๋ก ์ ๋ฆฌํ๊ฒ ์ต๋๋ค.
1. ์๋ก
์คํ๋ง์ ํต์ฌ ์๋ฆฌ๋ฅผ ์ดํด ํ๊ธฐ ์ํ ์์ ๊ฐ ํ์ํ์ต๋๋ค.
์์ ์๋ฐ๋ง์ ์ด์ฉํด ๋ค์์ ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ์ ๊ฐ์ง ํ๋ก์ ํธ๋ฅผ ๊ฐ๋ฐํด์ผํฉ๋๋ค.
๋น์ฆ๋์ค ์๊ตฌ์ฌํญ๊ณผ ์ค๊ณ
- ํ์
- ํ์์ ๊ฐ์
ํ๊ณ ์กฐํํ ์ ์๋ค.
- ํ์์ ์ผ๋ฐ๊ณผ VIP ๋ ๊ฐ์ง ๋ฑ๊ธ์ด ์๋ค.
- ํ์ ๋ฐ์ดํฐ๋ ์์ฒด DB๋ฅผ ๊ตฌ์ถํ ์ ์๊ณ , ์ธ๋ถ ์์คํ
๊ณผ ์ฐ๋ํ ์ ์๋ค. (๋ฏธํ์ )
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ
- ํ์์ ์ํ์ ์ฃผ๋ฌธํ ์ ์๋ค.
- ํ์ ๋ฑ๊ธ์ ๋ฐ๋ผ ํ ์ธ ์ ์ฑ
์ ์ ์ฉํ ์ ์๋ค.
- ํ ์ธ ์ ์ฑ
์ ๋ชจ๋ VIP๋ 1000์์ ํ ์ธํด์ฃผ๋ ๊ณ ์ ๊ธ์ก ํ ์ธ์ ์ ์ฉํด๋ฌ๋ผ. (๋์ค์ ๋ณ๊ฒฝ ๋ ์ ์
๋ค.)
-ํ ์ธ ์ ์ฑ
์ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ํ์ฌ์ ๊ธฐ๋ณธ ํ ์ธ ์ ์ฑ
์ ์์ง ์ ํ์ง ๋ชปํ๊ณ , ์คํ ์ง์ ๊น์ง ๊ณ ๋ฏผ์
๋ฏธ๋ฃจ๊ณ ์ถ๋ค. ์ต์
์ ๊ฒฝ์ฐ ํ ์ธ์ ์ ์ฉํ์ง ์์ ์ ๋ ์๋ค. (๋ฏธํ์ )
๊ฐ์ฒด ์งํฅ์ ํต์ฌ์ธ ๋คํ์ฑ์ ์ด์ฉํด ์ญํ (์ธํฐํ์ด์ค) ๊ณผ ๊ตฌํ (์ค์ ๊ตฌํ ๊ฐ์ฒด)์ผ๋ก ๋๋ ์ ๊ฐ๋ฐํ์ฌ ์์ ๋กญ๊ฒ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝํ ์ ์๊ฒ ํ์ต๋๋ค. ๋คํ์ฑ์ ์ด์ฉํด ๊ฐ๋ฐํ ๋๋ถ์ ํ์ ์ ์ฅ์๋ ๋ฌผ๋ก ์ด๊ณ , ํ ์ธ ์ ์ฑ ๋ ์ ์ฐํ๊ฒ ๋ณ๊ฒฝํ ์ ์๋ ์ํ๋ฅผ ๋ง๋ค์์ต๋๋ค. ์๋ฌด๋ฐ ๋ฌธ์ ๊ฐ ์์ด๋ณด์ด์ง๋ง! ์๋ก์ด ํ ์ธ ์ ์ฑ ์ ๊ฐ๋ฐํ๊ณ ์ ์ฉํ ๋ ๋ช๊ฐ์ง์ ๋ฌธ์ ๋ค์ด ์๊น๋๋ค.
๊ทธ ๋ฌธ์ ๋ค์ ์ค์ ์ผ๋ก ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
2. ์๋ก์ด ํ ์ธ ์ ์ฑ ๊ฐ๋ฐ ์ ๋ฌธ์ ์
๋๊ฐ์ง ๋ฌธ์ ์ ์ด ์์ต๋๋ค. ๋ฐ๋ก ์์ ์ฒซ๋ฒ์งธ ํฌ์คํธ ์์ ๋์๋ ๋ด์ฉ์ฒ๋ผ
โป ๋คํ์ฑ ๋ง์ผ๋ก๋ OCP, DIP๋ฅผ ์งํฌ ์๋ ์์์ต๋๋ค.
1.๊ธฐ์กด์ ๊ณ ์ ํ ์ธ ์ ์ฑ
package com.mks.core.discount;
import com.mks.core.member.Grade;
import com.mks.core.member.Member;
public class FixDiscountPolicy implements DiscountPolicy{
private int discountFixAmount = 1000; //1000์ ํ ์ธ
@Override
public int discount(Member member, int price) {
if (member.getGrade() == Grade.VIP) {
return discountFixAmount;
}
else{
return 0;
}
}
}
2.์๋ก์ด ์ ๋ฅ ํ ์ธ ์ ์ฑ
package com.mks.core.discount;
import com.mks.core.member.Grade;
import com.mks.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;
}
}
}
3.OrderServiceImpl ํด๋์ค
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository = new MemoryMemberRepository();
//OrderServiceImpl์์ ์ง์ ์ฃผ์
ํด์ฃผ๊ธฐ ๋๋ฌธ์ ํ ์ธ ์ ์ฑ
์ด ๋ฐ๋๋ ๋ง๋ค ๋ณ๊ฒฝํด์ค์ผํจ
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
// private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member, itemPrice);
return new Order(memberId, itemName, itemPrice, discountPrice);
}
}
์ฐ์ ์์ 1๋ฒ์ฒ๋ผ ๊ธฐ์กด์ ๊ณ ์ ํ ์ธ ์ ์ฑ ์ด ์์์ต๋๋ค. ์๋ก์ด ํ ์ธ ์ ์ฑ ์ ๋ง๋ค๊ณ ์ ์ฉํด์ผ ํ๋๋ผ๋ ์ญํ ๊ณผ ๊ตฌํ์ ์ ๊ตฌ๋ถํ๊ธฐ ๋๋ฌธ์ 2๋ฒ์ฒ๋ผ ์๋ก์ด ์ ๋ฅ ํ ์ธ ์ ์ฑ ์ ์ฝ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค.
์๋ฌด๋ฐ ๋ฌธ์ ์ ์ด ์์ด๋ณด์ด์ง๋ง 3๋ฒ OrderServiceImpl ํด๋์ค๋ฅผ ๋ณด๋ฉด ๋๊ฐ์ง ๋ฌธ์ ์ ์ ๋ฐ๊ฒฌํ ์ ์์ต๋๋ค.
๐ DIP ์์น ์๋ฐ - ์ถ์ํ์ ๊ตฌ์ฒดํ ๋๋ค ์์กด
OrderServiceImpl ํด๋์ค๋ MemberRepository ์ธํฐํ์ด์ค์ DiscountPolicy ์ธํฐํ์ด์ค๋ฅผ ์์กดํ๋ฉด์ ๊ตฌํ ํด๋์ค์ธ MemoryMemberRepository์ RateDiscountPolicy ๊น์ง๋ ์์กดํ๊ณ ์์ต๋๋ค. OrderServiceImpl ํด๋์ค๊ฐ ์ง์ ๊ฐ ์ธํฐํ์ด์ค์ ์ง์ ๊ตฌํ์ฒด๋ฅผ ์ฃผ์ ํ๋ฉฐ ์ธํฐํ์ด์ค, ๊ตฌํ์ฒด ๋ชจ๋๋ฅผ ์์กดํ๊ณ ์์์ ์ ์ ์์ต๋๋ค.
์ด๋ DIP ์์น์ ์๋ฐ ๋๋ ๊ฒ์ ๋๋ค.
๐ OCP ์์น ์๋ฐ - ํ ์ธ ์ ์ฑ ๋ณ๊ฒฝ ์๋ง๋ค client ์ฝ๋๋ฅผ ์์
OrderServiceImpl ํด๋์ค์ ์ฃผ์์ ์จ ์๋ฏ์ด OrderServiceImpl ์์ ์ง์ ์ค์ ํ ์ธ ์ ์ฑ ๊ตฌํ์ฒด๋ฅผ ์ฃผ์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ ํ ์ธ ์ ์ฑ ์ด ๋ฐ๋๋ ๋ง๋ค ์ง์ ๋ณ๊ฒฝํด์ค์ผ ํฉ๋๋ค.
์ด๋ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ์ํด client ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ OCP ์์น์ ์๋ฐ๋๋ ๊ฒ ์ ๋๋ค.
3. ํด๊ฒฐ์ฑ - ๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ!
ํ์ฌ ์ํ๋ ์ฃผ๋ฌธ ์๋น์ค ๊ตฌํ์ฒด๊ฐ ์ฃผ๋ฌธ ์๋น์ค๋ง์ ์ฑ ์์ง๊ณ ์ ๊ณตํ๋ ๊ฒ ๋ฟ๋ง ์๋๋ผ ์ด๋ค ํ ์ธ ์ ์ฑ ์ ์ฌ์ฉํด์ผํ๋์ง๊น์ง ์ง์ ๊ณ ๋ฅด๋ฉฐ ์ฑ ์์ง๊ณ ์์ต๋๋ค.
๋ค์ํ ์ฑ ์์ ๊ฐ๊ณ ์๋ ๊ฒ ์ ๋๋ค. ์ด๋ ๋ SRP ์์น์ ์๋ฐํ๊ธฐ๋ ํฉ๋๋ค.
๊ด์ฌ์ฌ๋ฅผ ๋ถ๋ฆฌํ ํ์์ฑ์ด ์๊น๋๋ค. ๊ฐ์ฒด๋ ์์ ์ ์ฌ์ฉ ์ญํ ์๋ง ์ถฉ์คํ๋ฉด ๋์ง ๊ตฌ์ฑ๊น์ง ์ฑ ์์ง ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ ์ ์ฒด ๋์ ๋ฐฉ์์ ๊ตฌ์ฑํด์ฃผ๊ธฐ ์ํ (๊ฐ์ฒด ์์ฑ ๋ฐ ์ฐ๊ฒฐ(์ฃผ์ )) ๋ณ๋์ ์ค์ class๊ฐ ํ์ํด์ง๋๋ค.!
๊ด์ฌ์ฌ์ ๋ถ๋ฆฌ๊ฐ ์ด๋ค์ง๋๋ค!
=> ๊ฐ์ฒด ์์ฑ ๋ฐ ์ฐ๊ฒฐ(์ฃผ์
)๊ณผ ๋น์ฆ๋์ค ๋ก์ง์ ์คํํ๋ ๋ถ๋ถ์ด ๊ฐ๊ฐ์ ์ฑ
์์ ๊ฐ๊ณ ๋ถ๋ฆฌ๊ฐ ๋ฉ๋๋ค. (์คํ ์ฑ
์ / ๊ตฌ์ฑ ์ฑ
์)
AppConfig.java
public class AppConfig {
// ์ ํ๋ฆฌ์ผ์ด์
์ ์ฒด ๋์ ๋ฐฉ์์ ๊ตฌ์ฑํด์ฃผ๊ธฐ ์ํ ๋ณ๋์ ํด๋์ค (๊ฐ์ฒด ์์ฑ ๋ฐ ์ฐ๊ฒฐ/์ฃผ์
๋ง์ ๋ด๋นํจ)
public MemberService memberService(){
return new MemberServiceImpl(new MemoryMemberRepository());
}
public OrderService orderService(){
return new OrderServiceImpl(new MemoryMemberRepository(), new FixDiscountPolicy());
}
}
AppConfig ํด๋์ค ๋ด์ memberService ๋ฉ์๋๋ MemberService์ ๊ตฌํ์ฒด์ธ MemberServiceImpl๋ฅผ ๋ฐํํฉ๋๋ค. MemberServiceImpl ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ MemberRepository์ ๊ตฌํ์ฒด์ธ MemoryMemberRepository ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํด์ค๋๋ค.
์์ ๊ฐ์ด
MemberServiceImpl ์์ฑ์๋ฅผ ํตํด ๊ตฌํ์ฒด์ธ MemoryMemberRepository ๊ฐ์ฒด๋ฅผ ์ฃผ์
ํด์ฃผ๋ ๊ฒ์ ์์ฑ์๋ฅผ ํตํ ์์กด์ฑ ์ฃผ์
์ด๋ผ๊ณ ํฉ๋๋ค.
MemberServiceImpl.java
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
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);
}
}
MemberServiceImpl๋ ์ด์ MemberRepository ์ธํฐํ์ด์ค์๋ง ์์กดํ๊ฒ ๋๋ฏ๋ก DIP ์์น์ ์งํค๊ฒ ๋ฉ๋๋ค.
OrderServiceImpl.java
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;
}
@Override
public Order createOrder(Long memberId, String itemName, int itemPrice) {
Member member = memberRepository.findById(memberId);
int discountPrice = discountPolicy.discount(member,itemPrice);
return new Order(memberId,itemName,itemPrice,discountPrice);
}
}
OrderServiceImpl๋ MemberRepository ์ธํฐํ์ด์ค์ DiscountPolicy ์ธํฐํ์ด์ค์๋ง ์์กดํ๋ฏ๋ก ๋ง์ฐฌ๊ฐ์ง๋ก DIP ์์น์ ์งํค๊ฒ ๋ฉ๋๋ค. ์์ ๊ฐ์ด MemberServiceImpl์ OrderServiceImpl๋ ์ธํฐํ์ด์ค์๋ง ์์กดํ๊ฒ ํจ์ผ๋ก์จ ์ฝ๋์์ผ๋ก๋ ์ด๋ ํ ๊ตฌํ ๊ฐ์ฒด๊ฐ ๋ค์ด์ฌ์ง๋ ์ ์ ์๊ณ , ์์ฑ์๋ฅผ ํตํด ์ธ๋ถ์์ ๊ตฌํ๊ฐ์ฒด๋ฅผ ์ฃผ์ ๋ฐ๊ฒ ๋ฉ๋๋ค.
AppConfig class์ ๋ฑ์ฅ์ผ๋ก ์ค์ class (AppConfig) ๋ฅผ ํตํด ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ฐ๊ฒฐ์ ์ํค๊ณ MemberServiceImpl์ OrderServiceImpl๋ ๊ฐ์ ์์ ์ ๋น์ฆ๋์ค ๋ก์ง์ ์คํ๋ง ํ๋ฉด ๋๋ฏ๋ก ์ญํ ์ ๋ถ๋ฆฌ๊ฐ ์ด๋ค์ง๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ฒ ์ธ๋ถ์์ MemberServiceImpl์ OrderServiceImpl์ ์ค์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ ๊ฒ์ DI (์์กด์ฑ ์ฃผ์ )์ด๋ผ๊ณ ํฉ๋๋ค.
AppConfig.java
public class AppConfig {
public MemberService memberService (){
return new MemberServiceImpl(memberRepository());
}
private MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
public OrderService orderService(){
return new OrderServiceImpl(memberRepository(), discountPolicy());
}
public DiscountPolicy discountPolicy (){
//return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
}
๋ํ ์์ ๊ฐ์ AppConfig ๋ฑ์ฅ ์ด์ ์๋ ๊ธฐ์กด ํ ์ธ ์ ์ฑ ์์ ์๋ก์ด ํ ์ธ ์ ์ฑ ์ ๋ฐ๊ฟ ๋ OrderServiceImpl ์์ ์ง์ ์ค์ ํ ์ธ ์ ์ฑ ๊ตฌํ์ฒด๋ฅผ ์ฃผ์ ํด์ฃผ๊ธฐ ๋๋ฌธ์ OrderServiceImpl์ ์ง์ ๋ณ๊ฒฝํด์ผํ์ต๋๋ค. ๊ทธ๋ก์ธํด OCP ์์น์ด ์๋ฐ๋์์์ต๋๋ค.
ํ์ง๋ง ์์ ๊ฐ์ AppCofig์ ๋ฑ์ฅํ๋ฉฐ ์ค์ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ ์ญํ ์ ๋ด๋นํ๊ธฐ ๋๋ฌธ์ AppConfig ์์๋ง ์ด๋ค ๊ตฌํ์ฒด๋ฅผ ์ฌ์ฉํ ์ง ์ ํ๋ฉด ๋๊ฒ ๋์์ต๋๋ค.
์ด๋ก ์ธํด OCP ์์น ๋ํ ์ง์ผ์ง๊ฒ ๋์์ต๋๋ค.
AppConfig ๋ฑ์ฅ ๊ฒฐ๊ณผ
AppConfig์ ๋ฑ์ฅ์ผ๋ก ๊ตฌํ ๊ฐ์ฒด๋ค์ ์์ ์ ๋ก์ง์ ์คํํ๋ ์ญํ ๋ง ๋ด๋นํ๊ฒ ๋์์ต๋๋ค.
๊ตฌํ ๊ฐ์ฒด์ ์ฃผ์ ์ AppConfig ๊ฐ ๋ด๋นํ๊ฒ ๋๋ฉฐ
ํ๋ก๊ทธ๋จ์ ์ ์ด ํ๋ฆ์ ์ด์ AppConfig ์์ ๋ด๋นํ๊ฒ ๋์์ต๋๋ค.
์ด๋ ๊ฒ ๋ช ํํ๊ฒ
์ค์ ๋ก์ง์ ๋ด๋นํ๋ ์ญํ ๊ณผ
๊ฐ ๊ตฌํ ๊ฐ์ฒด๋ค์ ์ฃผ์ ์์ผ์ฃผ๋ฉฐ ํ๋ก๊ทธ๋จ์ ์ ์ด ํ๋ฆ์ ๋ด๋นํด์ค ์ญํ ์ด ๋๋๋ฉฐ
๊ฐ์ฒด์งํฅ์ ์์น ์ค ์๋ฐ๋์๋ OCP ์์น DIP ์์น๊น์ง ์งํฌ ์ ์๊ฒ ๋์์ต๋๋ค.
๋
์คํ๋ง์ ๋ ์ฌ๋ฐ๋ฅด๊ฒ ์ฌ์ฉํ๊ธฐ ์ํด ๊น์ํ๋์ ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ฐ์๋ฅผ ๋ค์ผ๋ฉฐ ์ ๋ฆฌํ
๋๋ฒ์งธ ํฌ์คํธ์์ต๋๋ค.
์คํ๋ง์ ์ ๋ง ํต์ฌ์ด ๋๋ DI (์์กด์ฑ ์ฃผ์
)๊ณผ IoC (์ ์ด์ ์ญ์ )์ ๋ํด ๋ค์ ํ๋ฒ
์์๋ณด๊ณ ๋ ๋ช
ํํ ์ ์ ์์์ต๋๋ค.
๊ฐ์ฌํฉ๋๋ค. ๐
์คํ๋ง ํต์ฌ์๋ฆฌ ์ฒซ๋ฒ์งธ ํฌ์คํธ
1. ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง
Reference