๐ ๋ค์ด๊ฐ๋ฉฐ
์ด๋ฒ ํฌ์คํ ์์๋ ์์ฉ ์๋น์ค๋ฅผ ๊ตฌํํ ๋ ํญ์ ์ ๋์ ์ผ ์ ์์ง๋ง ๋ฐ๋ฅด๋ฉด ์ข์ ๊ตฌํ ๋ฐฉ์์ ๋ํด์ ํฌ์คํ ํ๊ณ ์ ํฉ๋๋ค. API๋ฅผ ๊ฐ๋ฐํ ์๋ก ์ด ๊ธฐ๋ฅ์ ๋ํ ๋ก์ง์ ์ด๋์ ์์ด์ผ ํ ๊น? ํน์ ์์ฉ ์๋น์ค๊ฐ ์ด๋ ๊ฒ ๊ธธ์ด์ง๋๊ฒ ๋ง๋...? ์์ฃผ ๊ณ ๋ฏผํ๊ฒ ๋ฉ๋๋ค. ๋ฌผ๋ก ๋๋ฉ์ธ์ ์ํฉ, ํ๋ณ ๊ท์น์ ๋ฐ๋ผ ๋ฌ๋ผ์ง ์ ์๊ฒ ์ง๋ง ํต์์ ์ธ ๊ตฌํ ๋ฐฉ์์ ๋ํด ์ ๋ฆฌํด ๋ณด๊ณ ์ ํฉ๋๋ค.
๐ ์์ฉ ์๋น์ค๋
์์ฉ ์๋น์ค๋ ํํ ์์ญ๊ณผ ํจ๊ป ์ฌ์ฉ์์ ๋๋ฉ์ธ์ ์ฐ๊ฒฐํด์ฃผ๋ ๋งค๊ฐ์ฒด ์ญํ ์ ํฉ๋๋ค. ํํ ์์ญ์ด ์ฌ์ฉ์๋ก๋ถํฐ URL, ์์ฒญ ํ๋ผ๋ฏธํฐ, ์ฟ ํค, ํค๋ ๋ฑ์ ์ด์ฉํด์ ์ฌ์ฉ์๊ฐ ์ด๋ค ๊ธฐ๋ฅ์ ์คํํ๊ธฐ๋ฅผ ์ํ๋์ง ํ๋ณํ๊ณ ๊ทผ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ์์ฉ ์๋น์ค๋ฅผ ์คํํ๊ฒ ๋ฉ๋๋ค.
์์ฉ ์๋น์ค๋ ์คํํ๋๋ฐ ํ์ํ ์ ๋ ฅ๊ฐ์ ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ฐ๊ณ ์คํ ๊ฒฐ๊ณผ๋ฅผ ํํ ์์ญ์ผ๋ก ๋ฆฌํดํฉ๋๋ค. ์์ฉ ์๋น์ค์ ๋ฉ์๋๊ฐ ์๊ตฌํ๋ ํ๋ผ๋ฏธํฐ์ ํํ ์์ญ์ด ์ฌ์ฉ์๋ก๋ถํฐ ์ ๋ฌ๋ฐ์ ๋ฐ์ดํฐ๋ ํ์์ด ์ผ์นํ์ง ์๊ธฐ ๋๋ฌธ์ ํํ ์์ญ์ ์์ฉ ์๋น์ค๊ฐ ์์ฒญํ๋ ํ์์ผ๋ก ์ฌ์ฉ์ ์์ฒญ์ ๋ณํ ํฉ๋๋ค.
@GetMapping("/test")
public ModelAndView join(HttpServletRequest request){
String email = request.getParameter("email");
String password = request.getParameter("password")
//์ฌ์ฉ์์ ์์ฒญ์ ์์ฉ ์๋น์ค์ ๋ง๊ฒ ๋ณํ
JoinRequest joinReq = new JoinRequest(email, password);
//๋ณํํ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด์ ์์ฉ ์๋น์ค๋ฅผ ์คํ
joinService.join(joinReq);
...
}
์ด์ ๊ฐ์ ์์ฉ ์๋น์ค๋ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ๊ธฐ๋ฅ์ ์คํํฉ๋๋ค. ์์ฉ ์๋น์ค๋ ์ฌ์ฉ์๊ฐ ์์ฒญํ ๊ธฐ๋ฅ์ ์ํํ๊ธฐ ์ํด ๋ ํฌ์งํ ๋ฆฌ๋ก๋ถํฐ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์กฐํํ๊ณ , ์กฐํํ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์์ฉ ์๋น์ค์ ์ฃผ์ํ ์ญํ ์ ๋๋ฉ์ธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ์ฌ์ฉ์์ ์์ฒญ์ ์ฒ๋ฆฌํ๋ ๊ฒ์ผ๋ก ํํ ์์ญ์์ ๋ณด์์ ๋ ๋๋ฉ์ธ ์์ญ๊ณผ ํํ ์์ญ์ ์ฐ๊ฒฐํด ์ฃผ๋ ์ฐฝ๊ตฌ(facade) ์ญํ ์ ํ๊ฒ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์์ฉ ์๋น์ค๋ ์ฃผ๋ก ๋๋ฉ์ธ ๊ฐ์ฒด ๊ฐ์ ํ๋ฆ์ ์ ์ดํ๋ ๋ก์ง๋ค์ด ์๊ฒ ๋๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํ๋์ ํ๋ฆ์ ๋ณผ ์ ์๋ ํํ๋ก ๊ฐ๋ฐ๋ฉ๋๋ค.
public Response doFunc(Request req){
//1. ๋ ํฌ์งํฐ๋ฆฌ๋ก๋ถํฐ ์ ๊ทธ๋ฆฌ๊ฑฐํธ๋ฅผ ๊ตฌํ๋ค.
Aggregate agg = repository.findById(req.getId());
checkNull(agg)
//2. ์ ๊ทธ๋ฆฌ๊ฑฐํธ์ ๋๋ฉ์ธ ๊ธฐ๋ฅ์ ์คํํ๋ค.
agg.doSomething(req.getValue());
//3. ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํดํ๋ค.
return createSuccessfulResponse(agg);
}
๐ ์์ฉ ์๋น์ค ๊ตฌํ ๋ฐฉ์
๋๋ฉ์ธ ๋ก์ง ๋ฃ์ง ์๊ธฐ
์์ฉ ์๋น์ค๋ ๋๋ฌด ๋ณต์กํ์ง ์๊ณ ํ๋์ ํ๋ฆ์ ์ฝ์ ์ ์์ด์ผ ํฉ๋๋ค. ๋ง์ผ ํ ๋์ ๋ค์ด์ค์ง ์๊ฒ ๋ณต์กํ๋ค๋ฉด ์์ฉ ์๋น์ค์์ ๋๋ฉ์ธ ๋ก์ง์ ์ผ๋ถ๋ฅผ ๊ตฌํํ๊ณ ์์ง๋ ์์์ง ํ์ธํด์ผ ํฉ๋๋ค. ๋๋ฉ์ธ ๋ก์ง์ ๋๋ฉ์ธ ์์ญ๊ณผ ์์ฉ ์๋น์ค์ ๋ถ์ฐํด์ ๊ตฌํํ๋ฉด ์ฝ๋ ํ์ง์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค.
์ฒซ ๋ฒ์งธ ๋ฌธ์ ๋ ์ฝ๋์ ์์ง์ฑ์ด ๋จ์ด์ง๊ฒ ๋ฉ๋๋ค. ๋๋ฉ์ธ ๋ฐ์ดํฐ์ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ๋๋ฉ์ธ ๋ก์ง์ด ํ ์์ญ์ ์์นํ์ง ์๊ณ ์๋ก ๋ค๋ฅธ ์์ญ์ ์์นํ๋ค๋ ๊ฒ์ ๋๋ฉ์ธ ๋ก์ง์ ํ์ ํ๊ธฐ ์ํด ์ฌ๋ฌ ์์ญ์ ๋ถ์ํด์ผ ํฉ๋๋ค. ๋ ๋ฒ์งธ ๋ฌธ์ ๋ ์ฌ๋ฌ ์์ฉ ์๋น์ค์์ ๋์ผํ ๋๋ฉ์ธ ๋ก์ง์ ๊ตฌํํ ๊ฐ๋ฅ์ฑ์ด ๋์์ง๊ฒ ๋๋ค๋ ๊ฒ์ ๋๋ค. ์ด๋ ๋ฏ ์์ง๋๊ฐ ๋จ์ด์ง๊ณ ์ฝ๋ ์ค๋ณต์ด ๋ฐ์ํ๋ ๋ฌธ์ ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก ์ฝ๋์ ๋ณ๊ฒฝ์ ์ด๋ ต๊ฒ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ์ผ๊ฐํด์ผ ํฉ๋๋ค.
์ ์ ํ ์์ฉ ์๋น์ค์ ํฌ๊ธฐ
์์ฉ ์๋น์ค๋ ๋ณดํต ๋ค์์ ๋๊ฐ์ง ์ค ํ๋์ ๋ฐฉ์์ผ๋ก ๊ตฌํํฉ๋๋ค.
- ํ ์์ฉ ์๋น์ค ํด๋์ค์ ๋๋ฉ์ธ์ ๋ชจ๋ ๊ธฐ๋ฅ ๊ตฌํํ๊ธฐ
- ๊ตฌ๋ถ๋๋ ๊ธฐ๋ฅ๋ณ๋ก ์์ฉ ์๋น์ค ํด๋์ค๋ฅผ ๋ฐ๋ก ๊ตฌํํ๊ธฐ
ํ ์์ฉ ์๋น์คํด๋์ค์ ๋๋ฉ์ธ์ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ค๋ฉด ํ ๋๋ฉ์ธ๊ณผ ๊ด๋ จ๋ ๊ธฐ๋ฅ์ ๊ตฌํํ ์ฝ๋๊ฐ ํ ํด๋์ค์ ์์นํ๋ฏ๋ก ๊ฐ ๊ธฐ๋ฅ์์ ๋์ผ ๋ก์ง์ ๋ํ ์ฝ๋ ์ค๋ณต์ ์ ๊ฑฐํ ์ ์๋ค๋ ์ฅ์ ์ด ์กด์ฌํฉ๋๋ค. ๊ทธ๋ฌ๋ ํ ์๋น์ค ํด๋์ค์ ์ฝ๋ ์ค ์๊ฐ ์ปค์ง๋ค๋ ๋จ์ ์ด ์กด์ฌํฉ๋๋ค. ์ฝ๋ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ฒ ๋๋ค๋ฉด ์ฐ๊ด์ฑ์ด ์ ์ ์ฝ๋๊ฐ ํ ํด๋์ค์ ํจ๊ป ์์นํ๊ฒ ๋์ด ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ด๋ จ ์๋ ์ฝ๋๊ฐ ๋ค์์ฌ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ญ๋๋ค.
๊ตฌ๋ถ๋๋ ๊ธฐ๋ฅ๋ณ๋ก ์๋น์ค ํด๋์ค๋ฅผ ๊ตฌํํ๋ ๋ฐฉ์์ ํ ์์ฉ ์๋น์ค ํด๋์ค์์ ํ ๊ฐ ํน์ 2-3๊ฐ์ ๊ธฐ๋ฅ์ ๊ตฌํํฉ๋๋ค. ์ฟ ํฐ ๋๋ฉ์ธ์ด ์๋ค๊ณ ์น๋ค๋ฉด CouponUseService(์ฟ ํฐ ์ฌ์ฉ ๊ธฐ๋ฅ), CouponIssueService(์ฟ ํฐ ๋ฐ๊ธ ๊ธฐ๋ฅ), CouponHistoryService(์ฟ ํฐ ์ด๋ ฅ ์ ์ฅ) ๋ฑ์ผ๋ก ํด๋์ค๋ฅผ ์ฌ๋ฌ๊ฐ ๋ง๋ค์ด ๊ธฐ๋ฅ์ ๊ตฌํํ๊ฒ ๋ฉ๋๋ค. ํด๋น ๋ฐฉ์์ ์ฌ์ฉํ๋ฉด ํด๋์ค๋ ๋ง์์ง์ง๋ง ํ ํด๋์ค์ ๊ด๋ จ ๊ธฐ๋ฅ์ ๋ชจ๋ ๊ตฌํํ๋ ๊ฒ๊ณผ ๋น๊ตํ์ ๋ ์ฝ๋ ํ์ง์ ์ผ์ ์์ค์ผ๋ก ์ ์งํ๋๋ฐ ๋์์ด ๋ฉ๋๋ค.
๊ฐ ๊ธฐ๋ฅ๋ง๋ค ๋์ผํ ๋ก์ง์ ๊ตฌํํ์ฌ ์ฝ๋๊ฐ ์ค๋ณต๋๋ ๊ฒฝ์ฐ๋ ๋ค์๊ณผ ๊ฐ์ด ๋ณ๋ ํด๋์ค์ ๋ก์ง์ ๊ตฌํํด์ ์ฝ๋ ์ค๋ณต์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
// ๊ฐ ์์ฉ ์๋น์ค์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋ ๋ก์ง์ ๋ณ๋ ํด๋์ค๋ก ๊ตฌํ
public final class MemberServiceHelper {
public static Member findExistMember(MemberRepository repository, String memberId){
Member member = memberRepository.findById(memberId);
if(member == null) throw new NoMemberException(memberId);
return member;
}
}
//์์ฉ ์๋น์ค์์ ํด๋น ํด๋์ค๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํ
import static com.myshop.member.application.MemberServiceHelper.*;
public class ChangePasswordService{
private MemberRepository memberRepository;
public void changePassword(String memberId, String curPw, String newPw){
Member member = findExistingMember(memberRepository, memberId);
member.changePassword(currPw, mewPw);
}
}
์์ฉ ์๋น์ค์ ๊ฐ ๋ฆฌํด
์์ฉ ์๋น์ค์์ ์ ๊ทธ๋ฆฌ๊ฑฐํธ ์์ฒด๋ฅผ ๋ฆฌํดํ๋ฉด ๋๋ฉ์ธ์ ๋ก์ง ์คํ์ ์์ฉ ์๋น์ค์ ํํ ์์ญ ๋ ๊ณณ์์ ํ ์ ์๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ธฐ๋ฅ ์คํ ๋ก์ง์ ์์ฉ ์๋น์ค์ ํํ ์์ญ์ ๋ถ์ฐ์์ผ ์ฝ๋์ ์์ง๋๋ฅผ ๋ฎ์ถ๋ ์์ธ์ด ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์์ฉ ์๋น์ค๋ ํํ ์์ญ์ ํ์ํ ๋ฐ์ดํฐ๋ง ๋ฆฌํดํ๋ ๊ฒ์ด ๊ธฐ๋ฅ ์คํ ๋ก์ง์ ์์ง๋๋ฅผ ๋์ด๋ ๋ฐฉ๋ฒ์ ๋๋ค.
์ฐธ๊ณ : DDD START! ๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ ๊ตฌํ๊ณผ ํต์ฌ ๊ฐ๋ ์ตํ๊ธฐ
'Architecture' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
MVC ํจํด ์์๋ณด๊ธฐ (0) | 2023.11.03 |
---|---|
Layered Architecture ์์๋ณด๊ธฐ (1) | 2023.11.02 |
๋ฐฑ์๋ ์ํคํ ์ฒ ๊ฐ์(2) - DIP (0) | 2023.01.22 |
๋ฐฑ์๋ ์ํคํ ์ฒ ๊ฐ์ (0) | 2023.01.16 |