[๊ฐ์] ์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ 1
์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ - ์ธํ๋ฐ | ๊ฐ์
์คํ๋ง ์ ๋ฌธ์๊ฐ ์์ ๋ฅผ ๋ง๋ค์ด๊ฐ๋ฉด์ ์คํ๋ง์ ํต์ฌ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ , ์คํ๋ง ๊ธฐ๋ณธ๊ธฐ๋ฅผ ํ์คํ ๋ค์ง ์ ์์ต๋๋ค., ์คํ๋ง ํต์ฌ ์๋ฆฌ๋ฅผ ์ดํดํ๊ณ , ์ฑ์ฅํ๋ ๊ฐ๋ฐ์๊ฐ ๋์ด๋ณด์ธ์! ๐ฃ ํ์ธํด์ฃผ
www.inflearn.com
์ถ์ฒ: ๊น์ํ ๊ฐ์ฌ๋ ์คํ๋ง ํต์ฌ ์๋ฆฌ- ๊ธฐ๋ณธํธ
EJB๋ ๋๋ฌด ์ด๋ ค์ ์
ใด---> EJB ์ปจํ
์ด๋๋ฅผ ๋์ฒดํ๋ ์คํ๋ง
ใด---> EJB ์ํฐํฐ๋น์ ๋์ฒดํ๋ ํ์ด๋ฒ๋ค์ดํธ -> ์๋ฐ ํ์ค JPA
ํ์ฌ : JPA์ ๊ตฌํ์ฒด๋ก ํ์ด๋ฒ๋ค์ดํธ๋ฅผ ์ฃผ๋ก ์ฌ์ฉํจ
1.๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง
- ์คํ๋ง์ด๋?
์คํ๋ง ์ํ๊ณ
ํ์
์คํ๋ง ํ๋ ์์ํฌ,์คํ๋ง ๋ถํธ
์ ํ
์คํ๋ง ๋ฐ์ดํฐ(CRUD๊ธฐ๋ฅ, JPA๋ฅผ ๊ฐ์ฅ ๋ง์ด ์),
์คํ๋ง ์ธ์ , ์คํ๋ง ์ํ๋ฆฌํฐ, ์คํ๋ง RestDocs(API ๋ฌธ์ํ), ์คํ๋ง ๋ฐฐ์น(๋ฐฐ์น ์ฒ๋ฆฌ), ์คํ๋ง ํด๋ผ์ฐ๋ ๋ฑ...
๋ ๋ณด๊ณ ์ถ์ผ๋ฉด https://spring.io/projects
Spring | Projects
Spring Framework Provides core support for dependency injection, transaction management, web apps, data access, messaging, and more.
spring.io
- ์คํ๋ง ํ๋ ์์ํฌ
ํต์ฌ ๊ธฐ์ : ์คํ๋ง DI(Dependency Injection ์ ์ฝ์, ์์กด์ฑ ์ฃผ์ ) ์ปจํ ์ด๋, AOP, ์ด๋ฒคํธ, ๊ธฐํ
์น ๊ธฐ์ : ์คํ๋ง MVC, ์คํ๋ง WebFlux
๋ฐ์ดํฐ ์ ๊ทผ ๊ธฐ์ : ํธ๋์ ์ , JDBC, ORM, XML ์ง์
๊ธฐ์ ํตํจ : ์บ์, ์ด๋ฉ์ผ, ์๊ฒฉ์ ๊ทผ, ์ค์ผ์ค๋ง
ํ ์คํธ : ์คํ๋ง ๊ธฐ๋ฐ ํ ์คํธ ์ง์
์ธ์ด: ์ฝํ๋ฆฐ, ๊ทธ๋ฃจ๋น
->์คํ๋ง ํ๋ ์ ์ํฌ์ ๊ธฐ์ ๋ค์ ํธ๋ฆฌํ๊ฒ ์ฌ์ฉํ๊ฒ ํด ์ฃผ๋ ์คํ๋ง๋ถํธ - ์คํ๋ง ๋ถํธ
๋จ๋ ์ผ๋ก ์คํํ ์ ์๋ ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฝ๊ฒ ์์ฑ
Tomcat(์น ์๋ฒ) ๋ด์ฅ
starter ์ข ์์ฑ ์ ๊ณต
์คํ๋ง๊ณผ 3rd parth ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์๋ ๊ตฌ์ฑ, ๋ฉ์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๋ฒ์ ์ ์์์ ์ฑ๊ฒจ์ค
๋ฉํธ๋ฆญ,์ํ ํ์ธ, ์ธ๋ถ ๊ตฌ์ฑ ๊ฐํผ ํ๋ก๋์ ์ค๋น ๊ธฐ๋ฅ ์ ๊ณต
๊ด๋ก์ ์ํ ๊ฐ๊ฒฐํ ์ค์
์คํ๋ง ํ๋ ์์ํฌ์ ๋ณ๋๋ก ์ฌ์ฉํ๋ ๊ฒ์ ์๋
์คํ๋ง์ ํต์ฌ ์ปจ์
๊ฐ์ฒด์งํฅ ์ธ์ด(JAVA) ๊ฐ ๊ฐ์ง ๊ฐ๋ ฅํ ํน์ง(๋คํ์ฑ)์ ์ด๋ ค๋ด๋ ํ๋ ์์ํฌ
์ข์ ๊ฐน์ฑ ์งํฅ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๋ฐํ ์ ์๊ฒ ๋์์ฃผ๋ ํ๋ ์์ํฌ
- ์ข์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ด๋?
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ํน์ง : ์ ์ฐํ๊ณ ๋ณ๊ฒฝ์ด ์ฉ์ด, ๊ฐ์ฒด๋ค์ ๋ชจ์ -> ๋คํ์ฑ
์ ์ฐํ๊ณ ๋ณ๊ฒฝ์ด ์ฉ์ด, ํ์ฅ ๊ฐ๋ฅํ ์ค๊ณ
์ธํฐํ์ด์ค๋ฅผ ์์ ์ ์ผ๋ก ์ค๊ณํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํ๋ค.
- ์ข์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ 5๊ฐ์ง ์์น(SOLID)
SPR ๋จ์ผ ์ฑ ์ ์์น (Single Responsibility principle)
ํ ํด๋์ค๋ ํ๋์ ์ฑ ์. ๋ณ๊ฒฝ์ด ์์ ๋ ํ๊ธ ํจ๊ณผ๊ฐ ์ ์ผ๋ฉด ๋จ์ผ ์ฑ ์ ์์น์ ์ ๋ฐ๋ฅธ ๊ฒ.
OCP ๊ฐ๋ฐฉ-ํจ์ ์์น (Open/Closed principle)
ํ์ฅ์๋ ์ด๋ ค์์ง๋ง ๋ณ๊ฒฝ์๋ ๋ซํ ์๊ฒ ํ๋ค. ๋ณ๊ฒฝ์ ํ์ง ์์๋ ํ์ฅ์ด ์ฉ์ดํ๋๋ก ํ๋ค.
LSP ๋ฆฌ์ค์ฝํ ์นํ ์์น (Liskov substitution principle)
์์น์ ์งํจ๋ค. goFrontํด๋๊ณ ๋ค๋ก๊ฐ๋ฉด x
ISP ์ธํฐํ์ด์ค ๋ถ๋ฆฌ ์์น (Interface segration principle)
ํน์ ํด๋ผ์ด์ธํธ๋ฅผ ์ํ ์ธํฐํ์ด์ค ์ฌ๋ฌ ๊ฐ๊ฐ ๋ฒ์ฉ ์ธํฐํ์ด์ค ํ๋๋ณด๋ค ๋ซ๋ค.
DIP ์์กด๊ด๊ณ ์ญ์ ์์น (Dependency inversion principle)
๊ตฌํ ํด๋์ค๊ฐ ์๋ ์ธํฐํ์ด์ค์ ์์กดํด์ผ ํ๋ค.
ํ์ง๋ง ๋คํ์ฑ ๋ง์ผ๋ก๋ OCP์ DIP๋ฅผ ์งํฌ ์ ์๋ค.
- ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง
์คํ๋ง์ ๋คํ์ฑ + OCP, DIP๋ฅผ ๊ฐ๋ฅํ๊ฒ ์ง์ํ๋ค.
์ธํฐํ์ด์ค๋ฅผ ๋จผ์ ๋ง๋ค๊ณ ๊ตฌํํ๋๊ฒ ์ด์์ -> ํฅํ์ ํ์ํ๋ฉด ๋์ ๋ ๊ด์ฐฎ๋ค
2. ์์ ๋ง๋ค๊ธฐ
- ํ๋ก์ ํธ ์์ฑ
ํ๋จ์ฒ๋ผ ์ค์ ํด์ผ ๋ ๋น ๋ฅด๊ฒ ๋น๋ํ ์ ์์ต๋๋ค.
- ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ๊ณผ ์ค๊ณ
ํ์
- ๊ฐ์ , ์กฐํ ๊ฐ๋ฅ
- ์ผ๋ฐ, VIP ๋ฑ๊ธ ์์
- ํ์ ๋ฐ์ดํฐ๋ ์์ฒด DB๋ฅผ ๊ตฌ์ถํ๊ฑฐ๋ ์ธ๋ถ ์์คํ ๊ณผ ์ฐ๋ํ ์ ์๋ค.(๋ฏธํ์ )
์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ
- ํ์์ ์ํ์ ์ฃผ๋ฌธํ ์ ์์
- ํ์ ๋ฑ๊ธ์ ๋ฐ๋ผ ํ ์ธ ์ ์ฑ ์ ์ ์ฉํ ์ ์์
- ๋ชจ๋ VIP๋ 1000์ ๊ณ ์ ๊ธ์ก ํ ์ธ (๋ฏธํ์ )
- ํ์ ๋๋ฉ์ธ ์ค๊ณ
์คํ๋ง์ ๋นผ๊ณ ํด๋ณธ๋ค.
- ํ์ ๋๋ฉ์ธ ๊ฐ๋ฐ
1. ๋ฉค๋ฒ, ๋ฑ๊ธ ์ํฐํฐ
//Grade.java
public enum Grade {
BASIC,
VIP
}
//Member.java
public class Member {
private Long id;
private String name;
private Grade grade;
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
public Long getId() {
return id;
}
public String getName() {
return name;
}
public Grade getGrade() {
return grade;
}
public Member(Long id, String name, Grade grade) {
this.id = id;
this.name = name;
this.grade = grade;
}
}
2. ๋ฉ๋ชจ๋ฆฌ ์ธํฐํ์ด์ค
//MemberRepository.java
public interface MemberRepository {
void save(Member member);
Member findById(Long memberId);
}
๋ฉ๋ชจ๋ฆฌ ๊ตฌํ
//MemoryMemberRepository.java
public class MemoryMemberRepository implements MemberRepository {
private static Map<Long,Member> store = new HashMap<>();//์ค๋ฌด์์๋ concurrency map ์ฌ์ฉ
@Override
public void save(Member member){
store.put(member.getId(), member);
}
@Override
public Member findById(Long memberId) {
return store.get(memberId);
}
}
3. ์๋น์ค ์ธํฐํ์ด์ค
//MemberService.java
public interface MemberService {
void join(Member member);
Member findMember(Long memberId);
}
์๋น์ค ๊ตฌํ
//MemberServiceImpl.java
public class MemberServiceImpl implements MemberService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
@Override
public void join(Member member) {
memberRepository.save(member);
}
@Override
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
}
์ถ์ํ์ ๊ตฌํ์ฒด๋ฅผ ๋ชจ๋ ์์กดํ๋ค -> DIP์ ๋ฌธ์ ๊ฐ ์๋ค.
MemverServiceImpl์
private final MemberRepository memberRepository = new MemoryMemberRepository();
์ด ๋ฌธ์ฅ์์ MemberRepository๋ฅผ ์ ์ธํจ์ผ๋ก์จ ์ธํฐํ์ด์ค์ ์์กดํ๊ณ ์์ผ๋,
๊ตฌํ์ฒด๋ฅผ new MemoryMemberRepository(); ๋ก ์ง์ ์ ์ด์ค์ผ๋ก์จ ๊ตฌํ์ฒด์๋ ์์กดํ๊ณ ์๋ค๊ณ ๋ณผ ์ ์๋ค.
- ํ์ ๋๋ฉ์ธ ์คํ๊ณผ ํ ์คํธ
Test
์ผ๋ฐ ์๋ฐ ์ฝ๋๋ก ์ฒดํฌ๋ ๋งค๋ฒ ๋ก๊ทธ์ฐ์ด์ผ๋๊ณ ๋ถํธํจ
๊ทธ๋์ ์๋ ๊ธฐ๋ฅ ํ ์คํธ
given, when, then
//MemberServiceTest.java
import static org.assertj.core.api.Assertions.assertThat;//assertThat์ฌ์ฉ์ ์ํด ํ์
public class MemberServiceTest {
MemberService memberService = new MemberServiceImpl();
//Control+Alt+V ์ฌ์ฉํ๋ฉด ํธ๋ฆฌ
@Test
void join(){
//given
Member member = new Member(1L, "memberA", Grade.VIP);
//when
memberService.join(member);
Member findMember = memberService.findMember(1L);
//then
assertThat(member).isEqualTo(findMember);
}
}
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์ค๊ณ
์ ์ฅ์์ ํ ์ธ ์ ์ฑ ๋ง ์ ์ ํ๊ฒ ๋ค๋ฅธ ๊ฒ์ ๋ผ์์ฃผ๋ฉด ๋๋ค.
์ญํ ๋ค์ ํ๋ ฅ ๊ด๊ณ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฌ์ฉ ํ ์ ์์
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ๊ฐ๋ฐ
ํ ์ธ ์ ์ฑ ์ธํฐํ์ด์ค
//DiscountPolicy.java
public interface DiscountPolicy {
int discount(Member member, int price);
}
๊ณ ์ ๋ ํ ์ธ ์ ์ฑ ๊ตฌํ
//DiscountPolicy.java
public class FicDiscountPolicy 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;
}
}
์ฃผ๋ฌธ ๊ฐ์ฒด
//Order.java
public class Order {
private Long memberId;
private String itemName;
private int itemPrice;
private int discountPrice;
public Order(Long memberId, String itemName, int itemPrice, int discountPrice) {
this.memberId = memberId;
this.itemName = itemName;
this.itemPrice = itemPrice;
this.discountPrice = discountPrice;
}
public void setMemberId(Long memberId) {
this.memberId = memberId;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public void setItemPrice(int itemPrice) {
this.itemPrice = itemPrice;
}
public void setDiscountPrice(int discountPrice) {
this.discountPrice = discountPrice;
}
public Long getMemberId() {
return memberId;
}
public String getItemName() {
return itemName;
}
public int getItemPrice() {
return itemPrice;
}
public int getDiscountPrice() {
return discountPrice;
}
@Override
public String toString() {
return "Order{" +
"memberId=" + memberId +
", itemName='" + itemName + '\'' +
", itemPrice=" + itemPrice +
", discountPrice=" + discountPrice +
'}';
}
}
์ฃผ๋ฌธ ์ธํฐํ์ด์ค
// OrderService.java
public interface OrderService {
Order createOrder(Long memberID, String itemName, int itemPrice);
}
์ฃผ๋ฌธ ๊ตฌํ
// OrderService.java
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
private final DiscountPolicy discountPolicy = new FicDiscountPolicy();
@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);
}
}
ํ ์ธ๊ณผ ๊ด๋ จํ ์์ ์ด ์์ผ๋ฉด OrderService๋ ์ด๊ฑธ ๊ณ ๋ คํ์ง ์์๋ ๋จ - ์ ๋ ์ค๊ณ
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์คํ๊ณผ ํ ์คํธ
์ฒซ ๋ฒ์งธ ๋ฃ๊ณ ๋ ํ๊ธฐ :
์ด ์ด์ ์คํ๋ง ์ ๋ฌธ๋ถํฐ ๊ฐ์๋ฅผ ๋ค ๋ฃ๊ณ ๋ค์ ๊ฐ์์ธ ํต์ฌ ์๋ฆฌ๋ฅผ ๋ฃ๊ณ ์๋ค.
์คํ๋ง ์ ๋ฌธ์ ๋ค์ ๋๋ ์ด๊ฒ ๋ญ๊ฐ... ์ด๊ฑฐ ์ด๋ ๊ฒ ๋ฐฐ์์ ๋๊ธด ํ๋๊ฑด๊ฐ... ํ๋ ๊ธฐ๋ถ์ผ๋ก ๋๊น์ง ๋ค์๋๋ฐ
๊ทธ๊ฑธ ๋ค ๋ฃ๊ณ ๋์ ํต์ฌ์๋ฆฌ๋ฅผ ๋ค์ผ๋ ์ด์ ๊ทธ๋ ํ๋๊ฒ ๋ณด์ด๊ณ ์ดํด๊ฐ ๋๋ ๊ฒ ๊ฐ๋ค.
์ญ์ ๋๊น์ง ํด๋ด์ผ๋ผ...
ํ๊ธด ์ด๋ ์ง ์์๋๊ฒ ์์๋ ๋ด๊ฐ ๋ฐฐ์ ๋ ๊ฒ ์ค์!
๋ณต์ต ํ ํ๊ธฐ :
๋ญ๊ฐ ์ด์ ์ฝ๋๊ฐ ํ ๋ฒ๋ง ๋ด๋ ๋ญ ํ๋ ๊ฒ์ธ์ง ์ ์ ์๋ ์ํ๋ก ๋ณด๋๊น ์ ๊ธฐํจ
์์์ ธ๋์ค๋ ์๋ก์ด ๋ด์ฉ์ ๋์ณค๋ ๋ํ ์ผํ ๋ถ๋ถ์ ๋ณผ ์ ์๊ฒ ๋์๋ค.
๊ธฐ์ต์ด ์๋๋ ๋ถ๋ถ์ด ๊ฝค ๋ง๊ตฐ