728x90
1. ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ ์ ๋ฆฌ
- ๋ฐ์ดํฐ
- ํ์ ID
- ์ด๋ฆ
- ๊ธฐ๋ฅ
- ํ์ ๋ฑ๋ก
- ์กฐํ
- ์์ง DB ์ ์ ํ์ง ์์ ์ํฉ ← ์ด๋ผ๋ ์ค์
- ์ปจํธ๋กค๋ฌ : ์น MVC์ ์ปจํธ๋กค๋ฌ (API ์์ฑ ๋ฑ)
- ์๋น์ค : ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง
- ๋๋ฉ์ธ : ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ์ฅ / ๊ด๋ฆฌ๋๋ ๊ฒ
- ๋ฆฌํฌ์งํ ๋ฆฌ : ๋ฐ์ดํฐ ๋ฒ ์ด์ค ์ ๊ทผ / ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ DB์ ์ ์ฅ ๋ฐ ๊ด๋ฆฌ
- ์ธํฐํ์ด์ค๋ก ๊ตฌํ ํด๋์ค ๋ณ๊ฒฝ ๊ฐ๋ฅํ๊ฒ ์ค๊ณ(DB ์ ์ ์ ํจ)
- ๊ตฌํ์ฒด๋ก ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ์ ๊ฐ๋ฒผ์ด ๋ฐ์ดํฐ ์ ์ฅ์๋ก ๊ฐ๋ฐ ์งํ
2. ํ์ ๋๋ฉ์ธ๊ณผ ๋ ํฌ์งํ ๋ฆฌ ๋ง๋ค๊ธฐ
1. Member ํด๋์ค ์์ฑ
package hello.hellospring.domain;
public class Member {
private Long id; // database index์ ๊ฐ๊น์
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2. Member ๊ด๋ฆฌ repository interface ์ ์ธ
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import java.util.List;
import java.util.Optional;
public interface MemberRepository {
Member save(Member member);
Optional<Member> findById(Long id); // Optional = nullable, ์์ ์ ์์
Optional<Member> findByName(String name);
List<Member> findAll();
}
3. Member ๊ด๋ฆฌ repository ๊ตฌํ์ฒด
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
import java.util.*;
public class MemoryMemberRepository implements MemberRepository{
// id, object
private static Map<Long, Member> store = new HashMap<>();
// key ๊ฐ ์์ฑ
private static long sequence = 0L;
@Override
public Member save(Member member) {
member.setId(++sequence);
store.put(member.getId(), member);
return member;
}
@Override
public Optional<Member> findById(Long id) {
return Optional.ofNullable(store.get(id)); // nullable, ์์ ์ ์์.
}
@Override
public List<Member> findAll() {
return new ArrayList<>(store.values());
}
@Override
public Optional<Member> findByName(String name) {
return store.values().stream() // store์ ๋ด์ฉ๋ค ์ค์์
.filter(member -> member.getName().equals(name)) // name์ด ๊ฐ์ผ๋ฉด
.findAny();
}
// = select * from store where name = {name};
public void clearStore() {
store.clear();
}
}
3. ํ์ ๋ ํฌ์งํ ๋ฆฌ ํ ์คํธ ์ผ์ด์ค ์์ฑ
- ์ฝ๋๋ฅผ ์ฝ๋๋ก ๊ฒ์ฆ!
- Java์์๋ JUnit ํ๋ ์์ํฌ๋ก ํ ์คํธ๋ฅผ ์คํํ๋๋ก ํจ.
package hello.hellospring.repository;
import hello.hellospring.domain.Member;
//import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class MemoryMemberRepositoryTest {
MemberRepository repository = new MemoryMemberRepository();
@Test
public void save() {
Member member = new Member();
member.setName("sprint");
repository.save(member);
Member result = repository.findById(member.getId()).get();
// System.out.println("result = " + (result == member));
// Assertions.assertEquals(result, member);
assertThat(member).isEqualTo(result);
}
}
- assertion That์ด junit ์ Assertion์ผ๋ก๋ ํธํ๋์ง ์์
- import static org.assertj.core.api.Assertions.assertThat; ์ผ๋ก ํด๊ฒฐ ๊ฐ๋ฅ
@Test
public void findByName() {
Member member1 = new Member();
member1.setName("spring1");
repository.save(member1);
Member member2 = new Member();
member2.setName("spring2");
repository.save(member2);
Member result = repository.findByName("spring1").get();
assertThat(result).isEqualTo(member1);
}
@Test
public void findAll() {
Member member1 = new Member();
member1.setName("spring1");
repository.save(member1);
Member member2 = new Member();
member2.setName("spring2");
repository.save(member2);
List<Member> result = repository.findAll();
assertThat(result.size()).isEqualTo(2);
}
test์ method ์คํ ์์๋ ๋๋ค → ๋ชจ๋ ๋ ๋ฆฝ์ ์ผ๋ก ์คํ๋๋๋ก ํ๊ธฐ ์ํด์๋ ํ ์คํธ ํ repository(๋ ๋ญ๋ )๋ฅผ ํด๋ฆฌ์ดํด์ค์ผํจ.
// MemoryMemberRepository.java
...
public void clearStore() {
store.clear();
}
- ์ ์ฅ๋ ๊ฐ์ฒด๋ฅผ ์น ๋น์์ฃผ๋ ์ฝ๋
@AfterEach
public void afterEach() {
repository.clearStore();
}
TDD ⇒ Test ์ฃผ๋ ๊ฐ๋ฐ, ํ ์คํธ ์ผ์ด์ค๋ฅผ ๋จผ์ ๋ง๋ค๊ณ ๋์ ๊ตฌํ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ.
4. ํ์ ์๋น์ค ๊ฐ๋ฐ
public Long join(Member member) {
// ๋ฉค๋ฒ ์ด๋ฆ ์ค๋ณต ๋ฐฉ์ง
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.");
});;
memberRepository.save(member);
return member.getId();
}
- ifPresent = ์กด์ฌํ๋ค๋ฉด ์ดํ function ์คํ
- ์ข ๋ ๊ฐ๊ฒฐํ๊ฒ ๋ฉ์๋๋ก ๋นผ๋ด๋ฉด
public Long join(Member member) {
// ๋ฉค๋ฒ ์ด๋ฆ ์ค๋ณต ๋ฐฉ์ง
validateDuplicateMember(member);
memberRepository.save(member);
return member.getId();
}
private void validateDuplicateMember(Member member) {
memberRepository.findByName(member.getName())
.ifPresent(m -> {
throw new IllegalStateException("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.");
});
}
- ๋๋จธ์ง find ๊ด๋ จ ์๋น์ค ๊ตฌํ
// select all members
public List<Member> findMembers() {
return memberRepository.findAll();
}
public Optional<Member> findOne(Long memberId) {
return memberRepository.findById(memberId);
}
5. ํ์ ์๋น์ค ํ ์คํธ
- ํด๋์ค ์ด๋ฆ → Control + Shift + T ํ๋ฉด ์๋์ผ๋ก ํ ์คํธ ์์ฑ
- !? ํ ์คํธ ์ฝ๋์ ํจ์ ์ด๋ฆ ํ๊ธ๋ก ์จ๋ ๋จ
- given / when / then ๊ตฌ๋ฌธ์ผ๋ก ํ
์คํธ ์์ฑ
- ์ฃผ์ด์ง input์ ๋ฐ์์ ๋ → when ์ด๋ผ๋ ์ผ์ด์ค์ ๋ํด์ → then์ด๋ผ๋ ๊ฒฐ๊ณผ๊ฐ ๋์ค๋๋ก
class MemberServiceTest {
MemberService memberService = new MemberService(memberRepository);
MemoryMemberRepository memberRepository = new MemoryMemberRepository();
...
- member service์์ new MemberService() ๋ง์ผ๋ก ์์ฑ์ ํ๋ฉด ์์์ ๋ง๋ memberRepository ์๋ ๋ค๋ฅธ repository๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋จ.
- ๋น์ฅ์ MemoryMemberRepository์ store ๊ฐ static์ด๋ผ ๊ด์ฐฎ์ง๋ง ์๋๋ฉด ๋ฌธ์ ๋จ
- Member Service์์ ์๋ก MemberRepository๋ฅผ ์์ฑํ์ง ์๊ณ ๋ฐ์์์ service๋ฅผ ๊ตฌ๋ํ๊ฒ ๋๋ฉด ๊ฐ์ repository๋ฅผ ์ฌ์ฉํ๊ฒ ๋๊ฒ ์ฃ ?
public class MemberService {
// ๊ธฐ์กด
// private final MemberRepository memberRepository = new MemoryMemberRepository();
// ๋ณ๊ฒฝ
private final MemberRepository memberRepository;
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository;
}
- ์๋์ ๊ฐ์ด ์ธ๋ถ์์ ๋ฃ์ด์ฃผ๋๋ก ์ค๊ณํ๋ ๊ฒ์ Dependency Injection(์์กด์ฑ ์ฃผ์ ) ์ด๋ผ๊ณ ๋ถ๋ฆ
class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void beforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach
public void afterEach() {
memberRepository.clearStore();
}
728x90
'๐ฅ Web > โ Back-end | Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring ์ ๋ฌธ] 5. ํ์ ๊ด๋ฆฌ ์์ - ์น MVC ๊ฐ๋ฐ (0) | 2023.09.25 |
---|---|
[Spring ์ ๋ฌธ] 4. ์คํ๋ง ๋น๊ณผ ์์กด๊ด๊ณ (0) | 2023.09.25 |
[Spring ์ ๋ฌธ] 2. ์คํ๋ง ์น ๊ฐ๋ฐ ๊ธฐ์ด (0) | 2023.06.30 |
[Spring ์ ๋ฌธ] 1. ํ๋ก์ ํธ ํ๊ฒฝ ์ค์ (0) | 2023.06.29 |