์๋ ํ์ธ์!
์ด๋ฒ ์น์ ๋ถํฐ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ฝ๋ ์์ฃผ๋ก ์์ฑํด๋ณผ๊ฑฐ ๊ฐ์์!
๊ทธ๋ผ ๊ณ ๊ณ !!

1. ํ๋ก์ ํธ ์์ฑ
์ฐ์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์คํ๋ง์ ์์ํ๊ธฐ ์ ์ ์์ํ๊ฒ ์๋ฐ๋ก๋ง ๊ตฌํ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ์ฝ๋๊ฐ ๋ณ๊ฒฝ์ด ๋๋ ์ ์ฐํ๊ฒ ๋์ฒ๊ฐ ๊ฐ๋ฅํ ๊น์?
์ฐจ๊ทผ์ฐจ๊ทผ ์งํํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ํ๋ก์ ํธ ์์ฑ์ ํด๋ณด๊ฒ ์ต๋๋ค.
Java17๊ณผ IDE: IntelliJ๋ฅผ ์ค์นํ๊ณ , ์คํ๋ง ๋ถํธ ์คํํฐ ์ฌ์ดํธ๋ก ์ด๋ํด์ ์คํ๋ง ํ๋ก์ ํธ๋ฅผ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
์์ ๋งํฌ๊ฐ ์คํ๋ง ๋ถํธ ์คํํฐ ์ฌ์ดํธ ์ ๋๋ค.
๋ค์ด๊ฐ๋ณด๋ฉด..
์ด๋ฐ์์ผ๋ก ๋์ต๋๋ค.
์ฌ๊ธฐ์์ Project๋ Gradle - Groovy, Language๋ Java, Spring Boot๋ 3.4.4๋ก ํด๋ณผ๊ฒ์.
SNAPSHOT๊ณผ M2๋ ์์ง ๋ถ์์ ํ๋ค๊ณ ํด์ผํ๋? ๊ทธ๋์ ์์ ๋ ๋ฒ์ ์ค ์ต์ ๋ฒ์ ์ธ 3.4.4๋ก ํด๋ณด๊ฒ ์ต๋๋ค.
๋ฐ์ ๋ณด๋ฉด Project Metadata๋ผ๊ณ ์์ ๊ฒ๋๋ค.
์ฌ๊ธฐ์ Group์ hello, Artifact๋ core๋ก ์ ์ด๋ณด๊ฒ ์ต๋๋ค. (Group๊ณผ Artifact ์๋ฌด๊ฑฐ๋ ์ ์ด๋ ๋ฉ๋๋ค.)
Artifact๋ฅผ core๋ก ์ ์ผ๋ฉด Name๊ณผ Package name์ด ์๋์ผ๋ก core ๊ด๋ จ๋๊ฒ ์์ฑ๋ฉ๋๋ค.
Packaging์ Jar๋ก ํ๋ฉด ๋๊ณ , Java๋ 17๋ฒ์ ์ผ๋ก ํด๋ณผ๊ฒ์. ๋ ์ต์ ๋ฒ์ ์ผ๋ก ํด๋ด๋ ๋ฉ๋๋ค.
์์ ์๋ Dependencies๋ ์๋ฌด ๊ฒ๋ ์ถ๊ฐ(์ ํ) ์ ํ๋ฉด ๋ฉ๋๋ค.
์๋ฌด ๊ฒ๋ ์ ํ ์ ํ๋ฉด ์คํ๋ง ๋ถํธ๊ฐ ์คํ๋ง core์ชฝ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ง ๊ฐ์ง๊ณ ๋ช ๊ฐ ๊ฐ๋จํ ๊ตฌ์ฑํด์ค๋๋ค.
๊ทธ๋์ ๋ณ๋์ ์์กด ๊ด๊ณ๋ ์ค์ ํ์ง ์๊ณ ๋ฐ์ GENERATE ๋ฒํผ์ ๋๋ฅด๋ฉด core.zip์ผ๋ก ๋ค์ด๋ก๋ ๋ ํ ๋ฐ ๊ทธ๊ฑฐ ์์ถ ํ๋ฉด ๋ฉ๋๋ค.
์์ถ ํผ ๊ฒ์ ๊ณต๋ถํ๊ธฐ ์ข์? ํด๋๋ก ์ฎ๊ฒจ๋์ผ๋ฉด ๋ฉ๋๋ค.
ํ๋ก์ ํธ๋ฅผ ์ด์ด๋ณด๊ฒ ์ต๋๋ค.
ํ๋ก์ ํธ ์ด๊ธฐ ๋๋ฅด๊ณ ์๊น core ํด๋ ์ฎ๊ฒจ ๋์ ๊ฒฝ๋ก๋ก ๋ค์ด๊ฐ์
core์์ build.gradle์ ๋๋ฅด๊ณ ํ๋ก์ ํธ๋ฅผ ์ด์ด๋ณผ๊ฒ์.
๊ทธ๋ฌ๊ณ ์คํ๋ง์ด ์ ๋์ด ์๋์ง ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
์ผ์ชฝ core ํด๋์์ src ํด๋์์ main์์ java์์ hello์์ core๋ก ๋ค์ด๊ฐ๋ฉด coreApplication์ด ๋์ต๋๋ค.
coreApplication์ ๋ค์ด๊ฐ์ ์์ ์ด๋ก์ ์ผ๊ฐํ์ ๋๋ฅด๋ฉด ์คํ์ด ๋ฉ๋๋ค.
์ฑ๊ณต์ ์ผ๋ก ์คํ์ด ๋๋ฉด ์์ ์ฌ์ง์ฒ๋ผ ๋์ฌ ๊ฒ์ ๋๋ค.
๊ทธ๋ผ ๋ณธ๊ฒฉ์ ์ผ๋ก ์์ํด๋ณผ๊ฒ์!

2. ๋น์ฆ๋์ค ์๊ตฌ์ฌํญ๊ณผ ์ค๊ณ
๊ฐ๋ฐ์ ์์ํ๊ธฐ ์ ์ ์๊ตฌ์ฌํญ๊ณผ ์ค๊ณ ๋จ๊ณ๋ ํ์์ ๋๋ค.
ํ ๋ฒ ์๊ตฌ์ฌํญ ์ ๋ฆฌ์ ์ค๊ณ๋ฅผ ํด๋ณผ๊น์?
- ํ์
- ํ์์ ๊ฐ์ ํ๊ณ ์กฐํํ ์ ์์ต๋๋ค.
- ํ์์ ์ผ๋ฐ๊ณผ VIP ๋ ๊ฐ์ง ๋ฑ๊ธ์ด ์์ต๋๋ค.
- ํ์ ๋ฐ์ดํฐ๋ ์์ฒด DB๋ฅผ ๊ตฌ์ถํ ์ ์๊ณ , ์ธ๋ถ ์์คํ ๊ณผ ์ฐ๋ํ ์ ์์ต๋๋ค. (๋ฏธํ์ )
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ
- ํ์์ ์ํ์ ์ฃผ๋ฌธํ ์ ์์ต๋๋ค.
- ํ์ ๋ฑ๊ธ์ ๋ฐ๋ผ ํ ์ธ ์ ์ฑ ์ ์ ์ฉํ ์ ์์ต๋๋ค.
- ํ ์ธ ์ ์ฑ ์ ๋ชจ๋ VIP๋ 1,000์์ ํ ์ธํด์ฃผ๋ ๊ณ ์ ๊ธ์ก ํ ์ธ์ ์ ์ฉํด์ผ ํฉ๋๋ค. (๋์ค์ ๋ณ๊ฒฝ๋ ์๋..?)
- ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๋์ต๋๋ค. ํ์ฌ์ ๊ธฐ๋ณธ ํ ์ธ ์ ์ฑ ์ ์์ง ์ ํ์ง ๋ชปํ์๊ณ , ์คํ ์ง์ ๊น์ง ๊ณ ๋ฏผ์ ๋ฏธ๋ฃจ๊ณ ์ถ๋ค. ์ต์ ์ ๊ฒฝ์ฐ ํ ์ธ์ ์ ์ฉํ์ง ์์ ์๋ ์์ต๋๋ค. (๋ฏธํ์ )
์๊ตฌ์ฌํญ์ ๋ณด๋ฉด ํ์ ๋ฐ์ดํฐ, ํ ์ธ ์ ์ฑ ๊ฐ์ ๋ถ๋ถ์ ์ง๊ธ ๊ฒฐ์ ํ๊ธฐ ์ด๋ ค์ด ๋ถ๋ถ์ ๋๋ค.
๊ทธ๋ ๋ค๊ณ ์ด๋ฐ ์ ์ฑ ์ด ๊ฒฐ์ ๋ ๋๊น์ง ๊ฐ๋ฐ์ ๋ฌด๊ธฐํ ๊ธฐ๋ค๋ฆด ์๋ ์์ต๋๋ค.
๊ทธ๋ ์ง๋ง ์์์ ๊ฐ์ฒด ์งํฅ ์ค๊ณ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ์ผ๋ฏ๋ก, ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค๊ณ ๊ตฌํ์ฒด๋ฅผ ์ธ์ ๋ ์ง ๊ฐ์๋ผ์ธ ์ ์๋๋ก ์ค๊ณํ๋ฉด ๋ฉ๋๋ค!
์ฃผ์! ํ๋ก์ ํธ ํ๊ฒฝ์ค์ ์ ํธ๋ฆฌํ๊ฒ ํ๋ ค๊ณ ์คํ๋ง ๋ถํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๊ณ , ์ง๊ธ์ ์คํ๋ง ์๋ ์์ํ ์๋ฐ๋ก๋ง ๊ฐ๋ฐ์ ์งํํฉ๋๋ค. ์คํ๋ง ๊ด๋ จ์ ๋์ค์ ๋์ฌ ์์ ์ ๋๋ค.

3. ํ์ ๋๋ฉ์ธ
3-1. ํ์ ๋๋ฉ์ธ ์ค๊ณ
- ํ์
- ํ์์ ๊ฐ์ ํ๊ณ ์กฐํํ ์ ์์ต๋๋ค.
- ํ์์ ์ผ๋ฐ๊ณผ VIP ๋ ๊ฐ์ง ๋ฑ๊ธ์ด ์์ต๋๋ค.
- ํ์ ๋ฐ์ดํฐ๋ ์์ฒด DB๋ฅผ ๊ตฌ์ถํ ์ ์๊ณ , ์ธ๋ถ ์์คํ ๊ณผ ์ฐ๋ํ ์ ์์ต๋๋ค. (๋ฏธํ์ )
- ํ์ ๋๋ฉ์ธ ํ๋ ฅ ๊ด๊ณ
ํ๋ ฅ ๊ด๊ณ๋ ๊ธฐํ์๋ ๋ณผ ์ ์๋ ๊ทธ๋ฆผ์ ๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ํ์ ์๋น์ค๋ฅผ ํธ์ถํ๊ณ , ํ์ ์๋น์ค๋ ํ์ ๊ฐ์ ๊ณผ ํ์ ์กฐํ๋ผ๋ 2๊ฐ์ง ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
ํด๋ผ์ด์ธํธ, ํ์ ์๋น์ค, ํ์ ์ ์ฅ์=์ญํ / ๋ฉ๋ชจ๋ฆฌ ํ์ ์ ์ฅ์, DB ํ์ ์ ์ฅ์, ์ธ๋ถ ์์คํ ์ฐ๋ ํ์ ์ ์ฅ์=๊ตฌํ
- ํ์ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
ํ์ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ์ ํ์ ๋๋ฉ์ธ ํ๋ ฅ ๊ด๊ณ๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ๋ฐ์๋ค์ด ๊ตฌ์ฒดํํด์ ๋ง๋ค์ด๋ ๋๋ค.
ํ์ ๋ฐ์ดํฐ์ ์ ๊ทผํ๋ ๊ณ์ธต์ ๋ฐ๋ก ํ์ ์ ์ฅ์(MemberRepository)๋ผ๋ ์ธํฐํ์ด์ค๋ก ๋ง๋ค์์ต๋๋ค.
์ฐ์ , ๋ฉ๋ชจ๋ฆฌ ํ์ ์ ์ฅ์๋ถํฐ ๊ตฌํํด์ ํ์ ์๋น์ค(MemberService)๋ฅผ ์ธํฐํ์ด์ค๋ก ๋ง๋ค๊ณ ๊ทธ๊ฒ์ ๋ํ ๊ตฌํ์ฒด๋ก MemberServiceImpl์ ๋ง๋ค์์ต๋๋ค.
๊ตฌํํด์ผ ํ ๊ฒ์ ํ์ ๊ฐ์ ๊ณผ ํ์ ์กฐํ 2๊ฐ์ง ์ธ๋ฐ ์ MemberServiceImpl ํ๋๋ง ๊ตฌํ์ฒด์ผ๊น์?
์๋ํ๋ฉด, ํ์๊ณผ ๊ด๋ จ๋ ๋ชจ๋ ๊ธฐ๋ฅ๋ค์ ํ์ ์๋น์ค ํด๋์ค ์์ ๊ตฌํ๋์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
๊ทธ๋ฆฌ๊ณ , ํ์ ์ ์ฅ์์ธ MemberRepository๋ฅผ ์ธํฐํ์ด์ค๋ก ๋ง๋ค์ด์ MemberRepository์ ๋ํ ๊ตฌํ์ฒด๋ก MemoryMemberRepository์ DbMemberRepository๋ฅผ ๋ง๋ญ๋๋ค.
- ํ์ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ
ํด๋์ค ๋ค์ด์ด๊ทธ๋จ๊ณผ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ์ ์ฐจ์ด์
- ํด๋์ค ๋ค์ด์ด๊ทธ๋จ-
์์คํ ์ ์ ์ ์ธ ๊ตฌ์กฐ๋ฅผ ์ค๊ณํ๋๋ฐ ์ฌ์ฉํฉ๋๋ค.
์ด๋ค ํด๋์ค๊ฐ ์๊ณ , ํด๋์ค ๊ฐ์ ๊ด๊ณ(์์, ์ฐ๊ด, ์์กด, ์งํฉ ๋ฑ)์ ๋ํ๋ด๋ ๋ค์ด์ด๊ทธ๋จ์ ๋๋ค.
์ค์ ์๋ฒ๋ฅผ ์คํํ์ง ์๊ณ ํด๋์ค๋ง ๋ถ์ํด์ ๋ณผ ์ ์๋ ๊ฒ์ ๋๋ค.
-๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ-
์ค์ ์คํ์ค์ธ ๊ฐ์ฒด๋ค์ ์ํ๋ฅผ ํํํ๋ ๋ค์ด์ด๊ทธ๋จ์ ๋๋ค.
ํด๋์ค ๋ค์ด์ด๊ทธ๋จ์ ๊ธฐ๋ฐ์ผ๋ก ํน์ ์์ ์์ ์์ฑ๋ ๊ฐ์ฒด๋ค์ ๊ด๊ณ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
3-2. ํ์ ๋๋ฉ์ธ ๊ฐ๋ฐ
๋ณธ๊ฒฉ์ ์ผ๋ก ๊ฐ๋ฐ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ฐ์ member๋ผ๋ ํจํค์ง๋ฅผ ์์ฑํฉ๋๋ค.
๊ทธ๋ฌ๊ณ member ํจํค์ง ์์ ๋ฑ๊ธ์ ๋ํ๋ด๋ Grade ํด๋์ค๋ฅผ ๋ง๋ญ๋๋ค.
์ฃผ์ํ ์ ์ Grade ํด๋์ค๋ ๋ฐ์ ์ฌ์ง์ฒ๋ผ ์ด๊ฑฐํ ์ฆ, enum์ผ๋ก ๋ง๋ญ๋๋ค.
Grade ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ๋๋ฉด,
package hello.core.member;
public enum Grade {
}
์ด๋ฐ ์์ผ๋ก Grade๋ผ๋ enum ํด๋์ค๊ฐ ๋ง๋ค์ด ์ง๋๋ค.
package hello.core.member;
public enum Grade {
BASIC,
VIP
}
์ด ํด๋์ค ์์ ์ ํฌ๊ฐ ์๊ตฌ์ฌํญ์ ์ ์๋ ๋ฑ๊ธ ์ข ๋ฅ์ธ BASIC๊ณผ VIP๋ฅผ ์ ์์ต๋๋ค.
package hello.core.member;
public class Member {
}
๊ทธ๋ฆฌ๊ณ , Member ์ํฐํฐ๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
Member ์ํฐํฐ๋ java ํด๋์ค๋ก ์์ฑํฉ๋๋ค.
package hello.core.member;
public class Member {
private Long id;
private String name;
private Grade grade;
}
ํ์ ์ํฐํฐ๋ ์์ฑ์ด id, ์ด๋ฆ, ๋ฑ๊ธ ์ด 3๊ฐ์ง๊ฐ ์์ต๋๋ค.
๊ทธ๋ฌ๊ณ ์์ฑ์๋ฅผ ๋ง๋ค์ด๋ณผ๊ฑด๋ฐ, Mac์ command + n์ ๋์์ ๋๋ฅด๋ฉด ๋๊ณ , Window๋ Alt + Insert๋ฅผ ๋์์ ๋๋ฅด๋ฉด ๋ฉ๋๋ค.
public class Member {
private Long id;
private String name;
private Grade grade;
public Member(Long id, String name, Grade grade) {
this.id = id;
this.name = name;
this.grade = grade;
}
}
์๊น์ ๊ฐ์ ๋จ์ถํค๋ฅผ ๋๋ฌ์ ์ด๋ฒ์ Getter์ Setter๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
public class Member {
...
public Member(Long id, String name, Grade grade) {
...
}
//Getter
public Long getId() {
return id;
}
public String getName() {
return name;
}
public Grade getGrade() {
return grade;
}
//Setter
public void setId(Long id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setGrade(Grade grade) {
this.grade = grade;
}
}
Getter์ Setter๋ฅผ ๋ง๋ค ๋ ํญ๋ชฉ ๋ค ์ ํํ์๋ฉด ๋ฉ๋๋ค.
์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
์๊น ์๋ member ํจํค์ง์์ ์ฐํด๋ฆญํ์ฌ Javaclass์์ ์ด๋ฆ์ MemberRepository๋ก ํ์ฌ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด๋ณผ๊ฑฐ์์.
๋ง๋ค์ด๋ณด๋ฉด
package hello.core.member;
public interface MemberRepository {
}
์ด๋ฐ ์์ผ๋ก ๋์ฌ๊ฑฐ์์.
public interface MemberRepository {
void save(Member member);
Member findById(Long memberId);
}
์ธํฐํ์ด์ค๋ ํจ์์ ํํ๋ง ์ ์ํ๋ ๊ฒ์ด์ด์ ์ค๊ดํธ ์์ ๋ก์ง ์ฝ๋๊ฐ ์์ต๋๋ค.
์ธํฐํ์ด์ค์ธ MemberRepository๋ฅผ ๊ตฌํํ ํด๋์ค์ธ MemoryMemberRepository๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
์๊น์ ๊ฐ์ ํจํค์ง์ Javaclass ํํ๋ก ๋ง๋ค๊ณ , ๋ฐ์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํฉ๋๋ค.
package hello.core.member;
public class MemoryMemberRepository implements MemberRepository{
}
์ implements๋ฅผ ์ฌ์ฉํ๋๋ฉด MemberRepository๋ผ๋ ์ธํฐํ์ด์ค์์ ๋ง๋ค๊ธฐ๋ก ์ ํด๋์ ํจ์๋ค์ ๊ตฌํํ ํด๋์ค๋ผ๋ ๊ฒ์ ๋ช ์ํ๊ธฐ ์ํด์ ์ ๋๋ค.
๊ทผ๋ฐ ์ด๋ ๊ฒ ๋์ด์์ผ๋ฉด ๋นจ๊ฐ์ค์ด ๋ฐ ๊ฒ์ ๋๋ค.
public class MemoryMemberRepository implements MemberRepository{
@Override
public void save(Member member) {
}
@Override
public Member findById(Long memberId) {
return null;
}
}
window ๊ธฐ์ค Alt + Enter๋ฅผ ๋๋ฅด๊ณ ๋ฉ์๋ ๊ตฌํ์ ๋๋ฅด๋ฉด ์ธํฐํ์ด์ค์์ ์ ์ํ ํจ์๋ค์ ์ค๋ฒ๋ผ์ด๋ ํ๋ ๊ธฐ๋ฅ์ด ๋์ต๋๋ค.
import java.util.HashMap;
import java.util.Map;
public class MemoryMemberRepository implements MemberRepository{
private static Map<Long, Member> store = new HashMap<>();
@Override
public void save(Member member) {
store.put(member.getId(), member);
}
@Override
public Member findById(Long memberId) {
return store.get(memberId);
}
}
- private static Map<Long, Member> store = new HashMap<>();
Map์ 2๊ฐ์ ํ์ ์ ๊ฐ๊ณ ์๋ ๋ฐฐ์ด์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.
์ฒซ ๋ฒ์งธ ํ์ ์ ํด๋น ๊ฐ์ ๊ณ ์ ํค์ด๊ณ , ๋ ๋ฒ์งธ ํ์ ์ ํด๋น ๊ฐ์ value ์ ๋๋ค.
ํํ๊ฐ [ {1,์์}, {2,์ญ}, {3,์ฝ๋ฉ}] ์ด๋ฐ ๋๋์ ๋๋ค.
์ฌ๊ธฐ์์ Map<Long, Member>๋ ๊ณ ์ ํค๋ Long ํ์ , value๋ ์ด์ ์ ์ ํ Member ํด๋์ค ํ์ ์ ๋๋ค.
Member ํด๋์ค๋ id์ name๊ณผ grade๋ฅผ ๊ฐ๊ณ ์๋ ์งํฉ์ ๋๋ค. (1, ์์, VIP) ์๋ฐ ๋๋?
store๋ ๋ณ์ ์ด๋ฆ์ผ๋ก ์๋ฌด๊ฑฐ๋ ์ง์ ํด๋ ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ , Map์ ์ฌ๋ฌ ๊ฐ์ง ์ข ๋ฅ๊ฐ ์๋๋ฐ HashMap์ ํด์ ํ ์ด๋ธ์ ์ฌ์ฉํด์ ๋น ๋ฅธ ๊ฒ์ ์๋๋ฅผ ์ ๊ณตํ๋ Map ์ ๋๋ค.
HashMap์๋ put() ๊ธฐ๋ฅ๊ณผ get() ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
put()์ ๊ฐ์ ๋ฃ๋ ๊ธฐ๋ฅ์ด๊ณ , ์ธ์๊ฐ์ผ๋ก ๊ณ ์ ํค๊ณผ value 2๊ฐ๋ฅผ ๋ฃ์ด์ค์ผ ํฉ๋๋ค.
get()์ ๊ฐ์ ์ฐพ๋ ๊ธฐ๋ฅ์ด๊ณ , ๊ณ ์ ํค๋ง ์ธ์๊ฐ์ผ๋ก ๋ฃ์ด์ฃผ๋ฉด value๋ฅผ ์ฐพ์์ค๋๋ค.
์ฌ๊ธฐ์์๋ ๊ณ ์ ํค๊ฐ member.getId์ ๊ฐ์ ๋๋ค. value๋ member ์์ฒด์ ๋๋ค.
๊ทธ ๋ค์์ผ๋ก MemberService ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
package hello.core.member;
public interface MemberService {
void join(Member member); //ํ์ ๊ฐ์
Member findMember(Long memberId); //ํ์ ์กฐํ
}
ํ์ ๊ฐ์ ๊ณผ ํ์ ์กฐํ ๊ธฐ๋ฅ์ ๋ฃ๊ณ , ๊ตฌํ์ฒด์ธ MemberServiceImpl์ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
package hello.core.member;
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);
}
}
MemberService์ ๊ตฌํ์ฒด์ฌ์ implements๋ฅผ ์ฌ์ฉํ๊ณ , ์๊น์ฒ๋ผ Alt + Enter ํค๋ฅผ ๋๋ฌ ๋ฉ์๋ ๊ตฌํ์ ํฉ๋๋ค.
- private final MemberRepository memberRepository = new MemoryMemberRepository();
์ฌ๊ธฐ์ final์ ๋ณ๊ฒฝํ ์ ์๋ ๋ณ์๋ฅผ ์๋ฏธํฉ๋๋ค.
MemberRepository๋ ์ด๋ฏธ ๊ตฌ์ฑ์ด ์๋ฃ๋์ด์๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ MemberService์์ MemberRepository๊ฐ ๋ณ๊ฒฝ์ด ๋๋ฉด ์ ๋ฉ๋๋ค. ๋๋ฌธ์ final์ ์ฌ์ฉํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , MemberRepository์ ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ผ ํ๋๋ฐ memberRepository๋ผ๋ ๋ณ์๋ช ์ ์ฌ์ฉํ์ฌ MemoryMemberRepository์์ ๊ตฌํํ ๊ธฐ๋ฅ๋ค์ ๊ฐ์ ธ์ต๋๋ค. (MemoryMemberRepository๋ MemberRepository์ ๊ตฌํ์ฒด์ด๊ธฐ ๋๋ฌธ์)
3-3. ํ์ ๋๋ฉ์ธ ์คํ๊ณผ ํ ์คํธ
์์์ ํ์ ๋๋ฉ์ธ ๊ฐ๋ฐํ ๊ฒ์ ์คํ๊ณผ ํ ์คํธ๋ฅผ ํด๋ณผ ๊ฒ์ ๋๋ค.
๋จผ์ , core ํด๋ ์์ MemberApp์ด๋ผ๊ณ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
๊ทธ๋ฌ๊ณ ๋ฉ์ธ ํจ์๋ฅผ ๋ง๋ค๊ณ , Member๋ฅผ ํ์๊ฐ์ ํ๊ณ ์กฐํ๋ฅผ ํด๋ณผ ๊ฒ์ ๋๋ค.
package hello.core;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
public class MemberApp {
public static void main(String[] args) {
MemberService memberService = new MemberServiceImpl();
Member member = new Member(1L, "์์", Grade.VIP);
memberService.join(member);
Member findMember = memberService.findMember(1L);
System.out.println("new member = " + member.getName());
System.out.println("findMember = " + findMember.getName());
}
}
new MemberServiceImpl()์ ํตํด MemberServiceImpl์์ ๊ตฌํํ๋ join๊ณผ findMember๋ฅผ ์ง์ ์ฌ์ฉํด๋ณผ ๊ฒ์ ๋๋ค.
์ฐ์ , ๊ฐ์ ์ํฌ ํ์ ์ ๋ณด๋ฅผ ์์ฑํฉ๋๋ค.
new Member(1L, "์์", Grade.VIP);๋ฅผ ํตํด id๋ 1๋ฒ์ด๊ณ , ์ด๋ฆ์ ์์์ด๊ณ , ๋ฑ๊ธ์ VIP์ธ Member๋ฅผ ํ๋ ์์ฑํ์์ต๋๋ค.
ํด๋น ๋ฉค๋ฒ๋ฅผ ํ์๊ฐ์ ์ํค๊ธฐ ์ํด MemberService.join()์ ํธ์ถํ์ฌ MemoryMemberRepository์ store์ ์ ์ฅ๋๋๋ก ํ์ต๋๋ค.
๋ฐฉ๊ธ ์ ์ฅํ ํ์์ id๋ฅผ ํตํด ์กฐํํด๋ณด๊ฒ ์ต๋๋ค.
MemberService.findMember()๋ฅผ ํตํด ๋ฐฉ๊ธ ์ ์ฅํ "์์"์ ์กฐํํ ๊ฑด๋ฐ, "์์"์ id ๊ฐ์ 1์ด๊ธฐ ๋๋ฌธ์ ์ธ์๊ฐ์ผ๋ก 1์ ๋ฃ์ด์ค๋๋ค. (Long ํ์ ์ด์ด์ 1L)
ํธ์ถํ๋ฉด ๋ฆฌํด๊ฐ์ผ๋ก member๊ฐ ๋์ค๊ธฐ ๋๋ฌธ์ ์ฌ๊ธฐ์ ์ด์ ์ ๋ง๋ค์๋ getter๋ค์ ์ฌ์ฉํ์ฌ ์ด๋ฆ์ด๋ ๋ฑ๊ธ ๋ฑ์ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค. (findMember.getName())
์ด๋ฆ์ ํธ์ถํ์ผ๋ฏ๋ก ๊ฒฐ๊ณผ๋ ์ด๋ ๊ฒ ๋์ต๋๋ค.
์ฌ๊ธฐ๋ ๋ณด๋ฉด ์์๋ค์ํผ ์์ํ๊ฒ ์๋ฐ๋ง ์ฌ์ฉํ ๊ฒ์ด๊ณ , ์คํ๋ง ๊ด๋ จ ์ฝ๋๊ฐ 1๋ ์์ต๋๋ค.
๊ทผ๋ฐ, ์ด๋ ๊ฒ ์ ํ๋ฆฌ์ผ์ด์ ๋ก์ง์ผ๋ก ํ ์คํธ ํ๋ ๊ฒ์ ์ข์ ๋ฐฉ๋ฒ์ด ์๋๋๋ค.
JUnit ํ ์คํธ ํ๋ ์์ํฌ๋ฅผ ์ฌ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
์ด๋ฒ์๋ main ํจํค์ง๊ฐ ์๋ test ํจํค์ง ์์ ๋ง๋ค ๊ฒ์ ๋๋ค.
test ํจํค์ง ์์ java ์์ hello ์์ core ์์์ member ํจํค์ง๋ฅผ ๋ง๋ค์ด์ ๊ฑฐ๊ธฐ์ MemberServiceTest๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ญ๋๋ค.
package hello.core.member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
public class MemberServiceTest {
MemberService memberService = new MemberServiceImpl();
@Test
void join() {
//given //์ด๋ฐ ํ๊ฒฝ์ด ์ฃผ์ด์ก์ ๋
Member member = new Member(1L, "์์", Grade.VIP);
//when //์ด๋ ๊ฒ ํ์ ๋
memberService.join(member);
Member findMember = memberService.findMember(1L);
//then //์ด๋ ๊ฒ ๋๋ค
Assertions.assertThat(member).isEqualTo(findMember);
}
}
MemberService์ ๊ธฐ๋ฅ์ ํ ์คํธํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ๋ฉ์๋๋ค์ ์ฌ์ฉํ๊ธฐ ์ํ์ฌ new MemberServiceImpl()์ ํ์ต๋๋ค.
@Test๊ฐ ๋ถ์ ๋ฉ์๋๋ ํ ์คํธ๋ฅผ ์ํ ๋ฉ์๋๋ผ๊ณ ์ ์ธํ๋ annotation์ ๋๋ค.
ํ ์คํธ๋ ํฌ๊ฒ given, when, then 3๋จ๊ณ๋ก ์งํํฉ๋๋ค.
given์ ํ ์คํธ ํ๊ฒฝ์ ๊ฐ์ถ๋ ๋จ๊ณ์ด๊ณ , when์ ํ ์คํธ ํ ์ํฉ์ ์งํํ๋ ๋จ๊ณ์ด๊ณ , then์ ์์ํ๋๋ก ์ ์๋ํ๋์ง ํ ์คํธํ๋ ๋จ๊ณ์ ๋๋ค.
- Member member = new Member(1L, "์์", Grade.VIP);
- ํ ์คํธ ์ "์์"์ด๋ผ๋ ๋ฉค๋ฒํ ๋ณ์๋ฅผ ์์ฑํฉ๋๋ค.
- ํ์๊ฐ์ ์ ์ ํ์๊ฐ์ ์ฐฝ์ ํ์์ ์ ๋ณด๋ค์ ์ ์ด๋๊ธฐ๋ง ํ ์ํ์ ๋น์ทํฉ๋๋ค.
- memberService.join(member);
- ํ ์คํธ ํ ์ํฉ์ธ "์์"์ด๋ผ๋ ๋ฉค๋ฒ๋ฅผ ํ์๊ฐ์ ์ํค๋ ๋จ๊ณ์ ๋๋ค.
- ์ฌ๊ธฐ์ findMember๋ ํ์๊ฐ์ ํ ์ฌ์ฉ์๋ฅผ ์กฐํํ๋ ๊ธฐ๋ฅ์ ๋๋ค.
- Assertions.assertThat(member).isEqualTo(findMember);
- Assertions๋ JUnit์์ ์ ๊ณตํ๋ ํ
์คํธ ๋ฉ์๋๋ค์ ์งํฉ ํด๋์ค์
๋๋ค.
๊ทธ ์ค ์ ํฌ๋ assertThat()์ ์ฌ์ฉํฉ๋๋ค. - assertThat()์ ๋น๊ต ๋์์ ์ง์ ํ ์ ์์ต๋๋ค.
์ ํฌ๋ ๋งจ ์ฒ์ ์์ฑํ ๋ฉค๋ฒํ ๋ณ์๋ฅผ ๋น๊ต ๋์์ ์ง์ ํ์ต๋๋ค. - ํด๋น ๋ณ์๊ฐ MemberService.findMember()๋ฅผ ํตํด ์กฐํํด์ ๊ฐ์ ธ์จ ๋ฉค๋ฒ์ ๊ฐ์์ผ ํ ์คํธ๊ฐ ์ฑ๊ณตํฉ๋๋ค.
- Assertions๋ JUnit์์ ์ ๊ณตํ๋ ํ
์คํธ ๋ฉ์๋๋ค์ ์งํฉ ํด๋์ค์
๋๋ค.
ํ ์คํธ ์คํ์ ํด๋ณด๊ฒ ์ต๋๋ค.
์ ํ๋ฆฌ์ผ์ด์ ์ผ๋ก ํ ์คํธ๋ฅผ ํ ๋๋ ์ถ๋ ฅ์ ํ์ฌ ๋์ผ๋ก ๊ฒ์ ์ ํ๋๋ฐ JUnit์ ์ฌ์ฉํ๋ฉด ํ ์คํธ ์ฑ๊ณตํ๋ฉด ๋ฐ์ ์ฌ์ง์ฒ๋ผ ๋์ต๋๋ค.
์คํจํ๋ฉด ๋นจ๊ฐ์์ผ๋ก ๋จ๋ฉด์ X๋์ค๊ณ ๋ญ ์ค๋ฅ ๋น๋๋ค.
ํ ์คํธ๋ฅผ ๋ฉ์ธ ํจ์์ ํ์ง ์๋ ์ด์
๋ฉ์ธ ํจ์์์ ํ ์คํธ๋ฅผ ์งํํ๋ฉด ๊ฐ ํ์ธ์ ์ํด System.out.println()๊ณผ ๊ฐ์ ์ถ๋ ฅ ํจ์๋ฅผ ์จ์ ์ถ๋ ฅ ๋ก๊ทธ๋ฅผ ๋ด์ผ ํฉ๋๋ค.
์ด ๊ณผ์ ์ ๋งค์ฐ ๋ฒ๊ฑฐ๋กญ๊ณ ์ค์๊ฐ ์์ ์ ์์ด์ ํ์คํ๊ฒ โ๏ธ ํน์ โ๊ฐ ๋์ค๋ JUnit ํ ์คํธ๋ฅผ ์งํํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด ํ์ ๋๋ฉ์ธ ์ค๊ณ์๋ ๋ฌธ์ ์ ์ด ์์ต๋๋ค.
์ด๋ ๊ฒ ์ฝ๋๋ฅผ ์ง๋ฉด ํด๋ผ์ด์ธํธ๊ฐ ์ถ์ํ์๋ ๊ตฌ์ฒดํ์๋ ์์กดํ๊ณ ์์ต๋๋ค.
(ex. MemberService๊ฐ MemberRepository์๋ ์์กดํ๊ณ , MemoryMemberRepository์๋ ์์กดํฉ๋๋ค.)
DIP๋ฅผ ์๋ฐํ๋ ๊ฒ์ด์ฃ .
4. ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ
4-1. ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์ค๊ณ
- ์ฃผ๋ฌธ๊ณผ ํ ์ธ ์ ์ฑ
- ํ์์ ์ํ์ ์ฃผ๋ฌธํ ์ ์๋ค.
- ํ์ ๋ฑ๊ธ์ ๋ฐ๋ผ ํ ์ธ ์ ์ฑ ์ ์ ์ฉํ ์ ์๋ค.
- ํ ์ธ ์ ์ฑ ์ "๋ชจ๋ VIP๋ 1,000์์ ํ ์ธํด์ฃผ๋ ๊ณ ์ ๊ธ์ก ํ ์ธ์ ์ ์ฉํด๋ฌ๋ผ."์ ๋๋ค. (๋์ค์ ๋ณ๊ฒฝ๋ ์ ์๋ค)
- ํ ์ธ ์ ์ฑ ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ์ฑ์ด ๋๋ค. ํ์ฌ์ ๊ธฐ๋ณธ ํ ์ธ ์ ์ฑ ์ ์์ง ์ ํ์ง ๋ชปํ๊ณ , ์คํ ์ง์ ๊น์ง ๊ณ ๋ฏผ์ ๋ฏธ๋ฃจ๊ณ ์ถ๋ค. ์ต์ ์ ๊ฒฝ์ฐ ํ ์ธ์ ์ ์ฉํ์ง ์์ ์๋ ์๋ค. (๋ฏธํ์ )
- ์ฃผ๋ฌธ ๋๋ฉ์ธ ํ๋ ฅ, ์ญํ , ์ฑ ์
1. ์ฃผ๋ฌธ ์์ฑ: ํด๋ผ์ด์ธํธ๋ ์ฃผ๋ฌธ ์๋น์ค์ ์ฃผ๋ฌธ ์์ฑ์ ์์ฒญํฉ๋๋ค.
2. ํ์ ์กฐํ: ํ ์ธ์ ์ํด์๋ ํ์ ๋ฑ๊ธ์ด ํ์ํฉ๋๋ค. ๊ทธ๋์ ์ฃผ๋ฌธ ์๋น์ค๋ ํ์ ์ ์ฅ์์์ ํ์์ ์กฐํํฉ๋๋ค.
3. ํ ์ธ ์ ์ฉ: ์ฃผ๋ฌธ ์๋น์ค๋ ํ์ ๋ฑ๊ธ์ ๋ฐ๋ฅธ ํ ์ธ ์ฌ๋ถ๋ฅผ ํ ์ธ ์ ์ฑ ์ ์์ํฉ๋๋ค.
4. ์ฃผ๋ฌธ ๊ฒฐ๊ณผ ๋ฐํ: ์ฃผ๋ฌธ ์๋น์ค๋ ํ ์ธ ๊ฒฐ๊ณผ๋ฅผ ํฌํจํ ์ฃผ๋ฌธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
์ฐธ๊ณ : ์ค์ ๋ก๋ ์ฃผ๋ฌธ ๋ฐ์ดํฐ๋ฅผ DB์ ์ ์ฅํ๊ฒ ์ง๋ง, ์์ ๊ฐ ๋๋ฌด ๋ณต์กํด์ง ์ ์์ด์ ์๋ตํ๊ณ , ๋จ์ํ ์ฃผ๋ฌธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํฉ๋๋ค.
- ์ฃผ๋ฌธ ๋๋ฉ์ธ ์ ์ฒด
ํ ์ธ ์ ์ฑ ์ญํ ์ธํฐํ์ด์ค์์ ์ด๋ค ๋ฐฉ์์ผ๋ก ํ ์ธ์ ํ ๊ฑด์ง์ ๋ฐ๋ผ ๊ตฌํ์ฒด๋ฅผ ๋๋ด์ต๋๋ค.
๊ณ ์ ๊ธ์ก์ ํ ์ธํ๋ ์ ์ก ํ ์ธ ์ ์ฑ ๊ณผ % ํ ์ธํ๋ ์ ๋ฅ ํ ์ธ ์ ์ฑ ์ ํ ์ธ ์ ์ฑ ์ญํ ์ ๊ตฌํ์ฒด๋ก ๋ํ๋์ต๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์ฃผ๋ฌธ ์์ฑ์ ์์ฒญํ ์ฃผ๋ฌธ ์๋น์ค ์ญํ ์ธํฐํ์ด์ค๋ ํ์์ ๋ฑ๊ธ์ ํ์ธํด์ผํ๊ธฐ ๋๋ฌธ์ ํ์ ์ ์ฅ์ ์ญํ ์ด ํ์ํ๊ณ , ๋ฑ๊ธ์ ๋ฐ๋ผ ๊ฐ๊ฒฉ์ ํ ์ธํด์ค์ผํ๊ธฐ ๋๋ฌธ์ ํ ์ธ ์ ์ฑ ์ญํ ๋ ํ์ํฉ๋๋ค.
์ญํ ๊ณผ ๊ตฌํ์ ๋ถ๋ฆฌํด์ ์์ ๋กญ๊ฒ ๊ตฌํ ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝํ ์ ์๊ฒ ์ค๊ณํ์ต๋๋ค.
๋๋ถ์ ํ์ ์ ์ฅ์๋ ๋ชฐ๋ก ์ด๊ณ , ํ ์ธ ์ ์ฑ ๋ ์ ์ฐํ๊ฒ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ์ฃผ๋ฌธ ๋๋ฉ์ธ ํด๋์ค ๋ค์ด์ด๊ทธ๋จ
- ์ธํฐํ์ด์ค OrderService = ์ฃผ๋ฌธ ์๋น์ค ์ญํ
- OrderServiceImpl = ์ฃผ๋ฌธ ์๋น์ค ๊ตฌํ์ฒด
- ์ธํฐํ์ด์ค DiscountPolicy = ํ ์ธ ์ ์ฑ ์ญํ
- FixDiscountPolicy = ์ ์ก ํ ์ธ ์ ์ฑ
- RateDiscountPolicy = ์ ๋ฅ ํ ์ธ ์ ์ฑ
- ์ฃผ๋ฌธ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ1
ํ์์ ๋ฉ๋ชจ๋ฆฌ์์ ์กฐํํ๊ณ , ์ ์ก ํ ์ธ ์ ์ฑ (๊ณ ์ ๊ธ์ก)์ ์ง์ํด๋ ์ฃผ๋ฌธ ์๋น์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์์๋ ๋ฉ๋๋ค.
์ญํ ๋ค์ ํ๋ ฅ ๊ด๊ณ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ์ฃผ๋ฌธ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ค์ด์ด๊ทธ๋จ2
ํ์์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์๋ ์ค์ DB์์ ์กฐํํ๊ณ , ์ ๋ฅ ํ ์ธ ์ ์ฑ (์ฃผ๋ฌธ ๊ธ์ก์ ๋ฐ๋ผ % ํ ์ธ)์ ์ง์ํด๋ ์ฃผ๋ฌธ ์๋น์ค๋ฅผ ๋ณ๊ฒฝํ์ง ์์๋ ๋ฉ๋๋ค.
ํ๋ ฅ ๊ด๊ณ๋ฅผ ๊ทธ๋๋ก ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
4-2. ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ๊ฐ๋ฐ - ์ ์ก ํ ์ธ ์ ์ฑ (FixDiscountPolicy)
์์ ์ค๊ณ๋ฅผ ๋ฐํ์ผ๋ก ๊ฐ๋ฐ์ ํ ๋ฒ ํด๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ , hello ํด๋ ์์ core ํจํค์ง ์์ discount๋ผ๋ ํจํค์ง๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๊ณ ์ด ํจํค์ง ์์ DiscountPolicy ์ธํฐํ์ด์ค๋ฅผ ์์ฑํ๊ฒ ์ต๋๋ค.
package hello.core.discount;
import hello.core.member.Member;
public interface DiscountPolicy {
//@return ํ ์ธ ๋์ ๊ธ์ก
int discount(Member member, int price);
}
DiscountPolicy์ ๊ตฌํ์ฒด๊ฐ ๊ตฌํํด์ผ ํ ๋ฉ์๋๋ฅผ ์ง์ ํ์ต๋๋ค.
์ ์ธ์๊ฐ์ด 2๊ฐ์ผ๊น์?
ํ ์ธ์ ํ๋ ค๋ฉด ์ด ์ฌ๋์ Grade์ ๋ฌผ๊ฑด์ ๊ฐ๊ฒฉ์ ์์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
Grade๊ฐ VIP์ด๋ฉด ๊ตฌํ์ฒด์ ํ ์ธ ์ ์ฑ ์ ๋ฐ๋ผ ์ ๊ฐ๊ฒฉ์์ ํ ์ธ๋ ๊ฐ๊ฒฉ์ผ๋ก return์ ํด์ค๋๋ค.
๊ทธ๋ฌ๊ณ DiscountPolicy์ ๊ตฌํ์ฒด ์ค์ ์ ์ก ํ ์ธ ์ ์ฑ ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
์๊น์ฒ๋ผ discount ํจํค์ง ์์ FixDiscountPolicy ํด๋์ค๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
๋ง๋ค์ด๋ณด๋ฉด
package hello.core.discount;
import hello.core.member.Member;
public class FixDiscountPolicy implements DiscountPolicy {
@Override
public int discount(Member member, int price) {
return 0;
}
}
์ด๋ ๊ฒ ๋์ค๋๋ฐ ์ด๊ฒ์ ์์์ MemoryMemberRepository๋ ํ๋ ๊ฒ์ฒ๋ผ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ํด๋์ค๋ผ๊ณ ๋ช ์ํ๊ธฐ ์ํด์ implements๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋นจ๊ฐ ์ค์ด ๋จ๋๋ฐ ์ด ์ญ์ Alt + Enter ํค๋ฅผ ๋๋ฌ์ ๋ฉ์๋ ๊ตฌํ์ ํ๋ฉด ๋ฉ๋๋ค.
๋ฉ์๋ ๊ตฌํ ํ๋ฉด ์ค๋ฒ๋ผ์ด๋๋ฅผ ํ๊ฒ ๋๋๋ฐ ์๊น ์ธํฐํ์ด์ค์์ ์ ์ํ๋ discount ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ์ต๋๋ค.
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; //1,000์์ ํ ์ธํ๋ ค๊ณ
}
else {
return 0; //ํ ์ธํ ๊ธ์ก์ด ์๋ค๋ ๋ป
}
}
}
๋ง์ ๋ ๊ตฌํํด๋ณด์์ต๋๋ค.
ํ ์ธํ ๊ธ์ก์ 1,000์์ผ๋ก ์ ์ํ๊ธฐ ๋๋ฌธ์ private int discountFixAmout = 1000;๋ก ๋ณ์๋ฅผ ์ง์ ํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ํ ์ธ์ VIP๋ง ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ ํจ์์ if๋ฌธ์ ์ฌ์ฉํ์ต๋๋ค.
๋ง์ฝ์ VIP ๋ฑ๊ธ์ด๋ฉด discountFixAmount ๋ณ์๋ฅผ ๋ฆฌํดํ๊ฒ๋ ํ๊ณ , ์๋ ๊ฒฝ์ฐ 0์ผ๋ก ๋ฆฌํด๋๊ฒ ํ์์ต๋๋ค.
๊ทธ ๋ค์ ์ฃผ๋ฌธ ์๋น์ค ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด core ํจํค์ง ์์ order๋ผ๋ ํจํค์ง๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๊ณ order ํจํค์ง ์์ order ์ํฐํฐ ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
package hello.core.order;
public class Order {
private Long memberId; //ํ์ id
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 int calculatePrice() {
return itemPrice - discountPrice;
}
public Long getMemberId() {
return memberId;
}
public String getItemName() {
return itemName;
}
public int getItemPrice() {
return itemPrice;
}
public int getDiscountPrice() {
return 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;
}
//๋ฌธ์์ด ์ถ๋ ฅ์ ํ ๋ ๋ณด๊ธฐ ์ฝ๊ฒ ํ๋ ค๊ณ
@Override
public String toString() {
return "Order{" +
"memberId=" + memberId +
", itemName='" + itemName + '\'' +
", itemPrice=" + itemPrice +
", discountPrice=" + discountPrice +
'}';
}
}
๋จผ์ , ์ฃผ๋ฌธ ๋ฐ์ดํฐ๋ฅผ ๋ง๋ค๊ธฐ ์ํด์ ์ฃผ๋ฌธํ ์ฌ์ฉ์์ id๊ฐ ํ์ํ๊ณ ์ฃผ๋ฌธํ ๋ฌผํ์ ์ด๋ฆ, ๊ฐ๊ฒฉ๊ณผ ํ ์ธํ ๊ฐ๊ฒฉ์ด ํ์ํฉ๋๋ค.
๊ทธ๋์ ์ 4๊ฐ์ ํ๋(์ํฐํฐ ๋ด์ ๋ณ์๋ค)๋ฅผ ๊ฐ๊ฐ ๋ง๋ค์ด์ Alt + Insert ํค๋ฅผ ๋๋ฌ ์์ฑ์์ Getter, Setter๋ฅผ ์์ฑํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ์ฌ์ฉ์๊ฐ ๊ตฌ๋งคํ ์ต์ข ๋ฌผ๊ฑด ๊ฐ๊ฒฉ์ ๊ณ์ฐํ๊ธฐ ์ํ ๋น์ฆ๋์ค ๊ณ์ฐ ๋ก์ง์ผ๋ก calculatePrice๋ผ๋ ํจ์๋ฅผ ๊ตฌํํ์ต๋๋ค.
๋ํ ์ฃผ๋ฌธ ์ ๋ณด๋ฅผ ๋ฌธ์์ด๋ก ํธํ๊ฒ ์ถ๋ ฅํ๊ธฐ ์ํด์ Alt + Insert ํค๋ฅผ ๋๋ฌ์ toString()์ ์์ฑํ์ต๋๋ค.
๋ง์ง๋ง์ผ๋ก ์ฃผ๋ฌธ ์๋น์ค ์ธํฐํ์ด์ค์ ์ฃผ๋ฌธ ์๋น์ค ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
์ฐ์ ์ฃผ๋ฌธ ์๋น์ค ์ธํฐํ์ด์ค๋ถํฐ ๋ง๋ค๊ฑด๋ฐ์.
order ํจํค์ง ์์ OrderService๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
package hello.core.order;
public interface OrderService {
Order createOrder(Long memberId, String itemName, int itemPrice);
}
createOrder๋ Order๋ฅผ ์์ฑํ๋ ๋ฉ์๋ ์ ๋๋ค.
Order๋ฅผ ์์ฑํ๊ธฐ ์ํด ํ์ํ ํ์ id, ๋ฌผ๊ฑด ์ด๋ฆ, ๋ฌผ๊ฑด ๊ฐ๊ฒฉ์ ์ธ์๊ฐ์ผ๋ก ๊ฐ๊ณ Order๋ฅผ ์์ฑํด์ ๋ฆฌํดํ๋ ๊ธฐ๋ฅ์ ํฉ๋๋ค.
์ฃผ๋ฌธ ์๋น์ค ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
์๊น์ ๊ฐ์ order ํจํค์ง ์์ OrderServiceImpl์ด๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
package hello.core.order;
import hello.core.discount.DiscountPolicy;
import hello.core.discount.FixDiscountPolicy;
import hello.core.member.Member;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository = new MemoryMemberRepository();
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
//์ง๊ธ OrderService ์
์ฅ์์๋ "ํ ์ธ์ ๊ดํ ๊ฒ์ 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);
}
}
findById()๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์ ํด๋น ๊ธฐ๋ฅ์ ๊ตฌํํ๋ MemoryMemberRepository๋ฅผ ํ ๋น๋ฐ์์ต๋๋ค.
๋ํ, discountPrice๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด์ discount()๋ฅผ ๊ตฌํํ๋ FixDiscountPolicy๋ฅผ ํ ๋น๋ฐ์์ต๋๋ค.
createOrder๋ Order๋ฅผ ์์ฑํด์ ๋ฆฌํดํ๋ ๋ฉ์๋ ์ ๋๋ค.
ํ์ฌ Order๋ฅผ ์์ฑํ๊ธฐ ์ํด์๋ memberId์ itemName, itemPrice๋ฅผ ์ธ์๊ฐ์ผ๋ก ๋ฐ์์์ต๋๋ค.
ํ์ง๋ง, discountPrice๋ Order ์์๋ ์์ง๋ง, ์ฌ์ฉ์๊ฐ ์ฃผ๋ฌธ์ ์์ฒญํ ๋ ์ ๋ฌํ๋ ๊ฐ์ ์๋๊ธฐ ๋๋ฌธ์ OrderServiceImpl์ createOrder ํจ์ ์์์ ๊ณ์ฐ์ด ๋์ด์ผ ํฉ๋๋ค.
(int discountPrice = discountPolicy.discount(member, itemPrice);)
4-3. ์ฃผ๋ฌธ๊ณผ ํ ์ธ ๋๋ฉ์ธ ์คํ๊ณผ ํ ์คํธ - ์ ์ก ํ ์ธ ์ ์ฑ (FixDiscountPolicy)
ํ ์คํธ๋ฅผ ํ๊ธฐ ์ํด์ ์ฐ์ core๋ผ๋ ํจํค์ง ์์ OrderApp์ด๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
package hello.core;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import hello.core.order.Order;
import hello.core.order.OrderService;
import hello.core.order.OrderServiceImpl;
public class OrderApp {
public static void main(String[] args) {
MemberService memberService = new MemberServiceImpl();
OrderService orderService = new OrderServiceImpl();
Long memberId = 1L;
Member member = new Member(memberId, "์์", Grade.VIP);
memberService.join(member);
Order order = orderService.createOrder(memberId, "์ด์ฝ๋ฆฟ", 10000);
System.out.println("order = " + order);
ํ์ id์ ์ด๋ฆ๊ณผ ๋ฑ๊ธ์ด ์๋ Member๋ฅผ ์์ฑํ์ฌ MemberServiceImpl์์ ์ ๊ณตํ๋ ํ์๊ฐ์ (join)๊ธฐ๋ฅ์ ์ฌ์ฉํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ , ์ฃผ๋ฌธ์ ์์ฑํ๊ธฐ ์ํด OrderServiceImpl์์ ์ ๊ณตํ๋ createOrder๋ฅผ ์ฌ์ฉํ์ต๋๋ค.
๋ํ, ์ธ์๊ฐ์ผ๋ก ๋ฐฉ๊ธ ํ์๊ฐ์ ํ ํ์์ id์ ๋ฌผ๊ฑด ์ด๋ฆ, ๋ฌผ๊ฑด ๊ฐ๊ฒฉ์ ๋ฃ์ด์คฌ์ต๋๋ค.
"์์"์ด์ ๋ฑ๊ธ์ VIP์ด๊ธฐ ๋๋ฌธ์ Order๊ฐ ์์ฑ๋ ๋ ํ ์ธ๋ ๊ฐ๊ฒฉ(discountPrice)์ 1,000์์ด ๋์ด์ผํ ๊ฒ์ ๋๋ค.
ํ ์คํธ๋ฅผ ์งํํด๋ณด๊ฒ ์ต๋๋ค.
๊ฒฐ๊ณผ์์ ๋ณด๋ฉด ์์๋ค์ํผ discountPrice๊ฐ 1,000์์ผ๋ก ์ ์ค์ ๋์์ต๋๋ค.
๊ทผ๋ฐ ์ด ๊ฒ์ฌ ๋ฐฉ๋ฒ์ ์์์๋ ์๊ธฐํ๋ค์ํผ ์ข์ง ์์ ๋ฐฉ๋ฒ์ด๊ธฐ ๋๋ฌธ์ JUnit์ ์ฌ์ฉํด์ ํ ์คํธ ํด๋ณด๊ฒ ์ต๋๋ค.
๋ฐ์ Test๋ผ๋ ํด๋ ์์ hello ํด๋ ์์ core ํจํค์ง ์์์ order๋ผ๋ ํจํค์ง๋ฅผ ๋ง๋ค์ด ๊ฑฐ๊ธฐ์ OrderServiceTest๋ผ๋ ํด๋์ค๋ฅผ ๋ง๋ค์์ต๋๋ค.
package hello.core.order;
import hello.core.member.Grade;
import hello.core.member.Member;
import hello.core.member.MemberService;
import hello.core.member.MemberServiceImpl;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
public class OrderServiceTest {
MemberService memberService = new MemberServiceImpl();
OrderService orderService = new OrderServiceImpl();
@Test
void createOrder() {
Long memberId = 1L;
Member member = new Member(memberId, "์์", Grade.VIP);
memberService.join(member);
Order order = orderService.createOrder(memberId, "์ด์ฝ๋ฆฟ", 10000);
Assertions.assertThat(order.getDiscountPrice()).isEqualTo(1000);
}
}
์์์์ฒ๋ผ Assertions ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ํ ์คํธ๋ฅผ ์์ฑํ์ต๋๋ค.
VIP ๋ฑ๊ธ์ธ "์์"์ด๊ฐ 10,000์ ์ง๋ฆฌ์ธ ์ด์ฝ๋ฆฟ์ ์ฃผ๋ฌธํ๊ธฐ ๋๋ฌธ์ ํด๋น ์ฃผ๋ฌธ์ discountPrice๋ 1,000์์ด ๋์ด์ผ ํฉ๋๋ค.
ํ ์คํธ ๊ฒฐ๊ณผ๋ ์ ๋์์๊น์?
์ ๋์์ต๋๋ค.
๋๋ฌ์ต๋๋ค.
์ฌ๊ธฐ๊น์ง ๋์~
์ฒ์ ์ ๋๋ก ์คํ๋ง ๋ฐฐ์๋ณด๋๊ฑฐ๋ผ ์ซ ์ด๋ ต๋ค์..ใ
๋ค์์ ๋ ์ค๊ฒ ์ด๋ค
์๋ฝ!

'STUDY๐' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring ๊ธฐ๋ณธ] 4. ์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น๐ซ (0) | 2025.04.05 |
---|---|
[Spring ๊ธฐ๋ณธ] 3. ์คํ๋ง ํต์ฌ ์๋ฆฌ ์ดํด2- ๊ฐ์ฒด ์งํฅ ์๋ฆฌ ์ ์ฉ (2) | 2025.03.26 |
[Spring ๊ธฐ๋ณธ] 1. ๊ฐ์ฒด ์งํฅ ์ค๊ณ์ ์คํ๋ง (2) | 2025.03.19 |
[HTTP] 8. HTTP ํค๋2 - ์บ์์ ์กฐ๊ฑด๋ถ ์์ฒญ (1) | 2025.03.13 |
[HTTP] 7. HTTP ํค๋1 - ์ผ๋ฐ ํค๋๐ช (2) | 2025.03.09 |