controller의 임무? DAO의 임무?

1,976 views
Skip to first unread message

나창훈

unread,
Dec 16, 2010, 3:17:43 AM12/16/10
to ks...@googlegroups.com
안녕하세요~
 
개발을 하던중에 무언가 꼬이는거 같아서 이렇게 질문을 올려봅니다.
 
포인트 관련해서 동작을 하는 PointController,
 
사용자 관련해서 동작을 하는 UserController,
 
어플리케이션 관련해서 동작을 하는 ApplicationController
 
이렇게 3개의 컨트롤러가 있고
 
Point, user, application의 정보를 가지고 있는 테이블에
 
DB관련 액션을 하는 DAO들이 존재하고 있습니다.
(PointDAO, UserDAO, ApplicationDAO(
 
이런 상태에서
 
어플리케이션을 사용자가 포인트를 소비해서 사용한다라는 액션이 일어났을때
 
ApplicationController에서 PointController의 메소드를 호출해서
 
A라는 사용자가 포인트를 사용했다라는 부분을 테이블에 저장을 하고
 
A 사용자가 가지고 있던 포인트에서 소비한 포인트만큼을 사용자 테이블에서
 
빼는 작업을 구현하려고 하는데
 
PointController에서 UserController를 호출해서
 
UserDAO를 이용하여 포인트를 변경하느냐..
 
아니면 PointController에서 UserDAO를 이용하여
 
포인트를 변경하느냐 라는 부분이
 
걸려서 이렇게 질문을 드립니다.
 
controller를 타고서 가는게 맞나요?
 
아니면 DAO를 직접 사용해도 되는게 맞나요?;
 
 
맞나요라는 게 정답이 아닌거 같기도 하고;;
 
단계를 줄여서 가는게 맞는거 같기도 하구;;;
 
pointController에서 userController를 호출해서 가느냐..
 
아니면pointcontroller에서 userDao를 호출해서 가느냐;;
 
뭔가 고민할게 아닌데 고민하는거 같아서 답답하네요.ㅠ_ㅠ
 
제가 DAO와 controller의 역할(?) 의미(?)를 제대로 이해를 못한걸까요?
 
많은 분들의 의견 부탁드립니다..

원상호

unread,
Dec 16, 2010, 3:35:25 AM12/16/10
to ks...@googlegroups.com
중간에 Service 계층을 두는게 좋지 않을까요?
Controller는 웹 요청과 응답만을 처리하는 부분으로 생각하시고, 
실제 비즈니스 로직은 Service 계층에서 하는거죠.
즉 PointService, UserService 같은걸 만드시고, Controller는 서비스 메소드만 호출하는 겁니다.

서비스계층은 내부에서 Repository, Factory, Domain objects 같은걸 이용해서 로직을 구성하시고요.

또 이렇게 해야 서비스 메소드를 AOP 트랜잭션으로 묶을 수 있겠지요.

2010/12/16 나창훈 <huli...@gmail.com>
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.
그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.



--
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
* 원상호 (Won, Shawn), BPNR
* E-Mail (sh...@bpnr.co.kr, shaw...@gmail.com), Jabber ID : shaw...@gmail.com
* --- "The best way to predict the future is to invent it" - Alan Kay
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------

원상호

unread,
Dec 16, 2010, 3:36:09 AM12/16/10
to ks...@googlegroups.com
Repository는 DAO라고 보셔도 되겠죠?

2010/12/16 원상호 <shaw...@gmail.com>

나창훈

unread,
Dec 16, 2010, 3:52:18 AM12/16/10
to ks...@googlegroups.com
그럼 PointService에서 UserDAO 와 PointDAO를 이용해서
 
로직을 구현하면 된다는 말씀이신가요..?;;
 
아니면;; Service단에서 다른 Service를 이용하여 각각의 DAO에
 
접근(?)을 하도록 하여야 하는걸까요?
 
뭔가.. 답이 없는데 답을 여쭤보는거 같아 죄송스럽네요.;;;
 
그냥 서비스단을 만들어서 제 맘대로 하면 된다.........?;; 가 답일까요? ㅠ_ㅠ
 
다시한번 조언 부탁드립니다.
 
2010년 12월 16일 오후 5:36, 원상호 <shaw...@gmail.com>님의 말:

JUNG-LAE JO

unread,
Dec 16, 2010, 4:02:24 AM12/16/10
to ks...@googlegroups.com

특정데이터를 조작하는 작업은 특정데이터를 가지고 있는 인터페이스가 처리해야겠죠.
즉, 서비스단에서 서비스를 호출하는게 좋아보이네요.
각각의 서비스를 서로 다른 개발자가 구현한다했을때 서비스를 인터페이스 제공해놓고 각기 할 일 하면 되고요.

2010. 12. 16. 오후 5:52에 "나창훈" <huli...@gmail.com>님이 작성:

>>>> 이메일을 보내주세요.
>>>> 더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에서 그룹을 방문하세요.
>>>>
>>>
>>>
>>>
>>> --
>>>
>>> -----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
>>> * 원상호 (Won, Shawn), BPNR
>>> * E-Mail (sh...@bpnr.co.kr, shaw...@gmail.com), Jabber ID :
>>> shaw...@gmail.com
>>> * --- "The best way to predict the future is to invent it" - Alan Kay
>>>
>>> -----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
>>>
>>
>>
>>
>> --
>>
>> -----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
>> * 원상호 (Won, Shawn), BPNR
>> * E-Mail (sh...@bpnr.co.kr, shaw...@gmail.com), Jabber ID :
>> shaw...@gmail.com
>> * --- "The best way to predict the future is to invent it" - Alan Kay
>>
>> -----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
>>
>> --
>> Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
>> 이 그룹에 게시하려면 ks...@googlegroups.com(으)로 이메일을 보내세요.

Sungchul Park

unread,
Dec 16, 2010, 6:33:09 AM12/16/10
to ks...@googlegroups.com
간단하게 메일링으로 얘기하기엔 좀 어려운 주제네요.

일단 DAO를 Table Data Gateway 방식으로 만들었다고 생각이 됩니다. 간단히 말해서 테이블과 DAO가 1:1 관계인 상황이죠.

그리고 같은 구조로 Controller를 만들었고요.

지금 서 비스 계층를 도입한다고 해도 역시 point, user, application으로 나누면 뭔가 문제를 해결해야하는 위치만 바뀔 뿐 로직을 구성하는 방식에 대한 의문은 해결이 안되는 상황인 듯 하네요.

사실 서비스 계층을 무엇으로 정의하고 어떻게 써야하는지 논의하는 것도 상당히 논쟁적이고 결론내기 쉽지 않은 부분입니다. 하지만 여기서 그걸 다 논의할 수는 없겠지요.

한가지 도움이 될만한 원칙 비슷한 걸 말씀드리려고 합니다.

각 계층별로 객체를 구성하는 목적을 분리하십시오.

무슨 말이냐면... 지금 DAO를 테이블과 1:1 구조로 구성하셨는데 이건 출발이 좋습니다. DAO 계층은 테이블의 구조와 연계하여 객체를 구성하신 거죠.

그런데 컨트롤러도 테이블과 같거나 뭔가 영향을 받은 구조로 해야 할까요? 물론 아니겠죠. 컨트롤러는 화면에 따라 필요한 만큼 만드시면 됩니다. 이걸 Page Controller라고 부릅니다. 여기서 페이지는 화면일 수도 있고 Ajax의 개별 액션일 수도 있습니다. 한마디로 컨트롤러는 UI 객체이니 UI의 필요에 따라 만들어야 한다는 겁니다. 절대 테이블 구조에 영향을 받아서는 안 됩니다.

이런 방식으로 애플리케이션을 구성하는 가운데 문제의 "사용자가 포인트를 소비하는 액션"에 대한 로직을 어디에 두느냐는 문제를 어떻게 해결해야 할까요?

우선은 이 로직이 특정 화면이나 Ajax 호출에서만 사용된다면 굳이 서비스 계층을 만들 필요가 없습니다. PointController 같이 해당 UI를 처리할 컨트롤러를 만들면 되는 거죠. 이미 저희는 컨트롤러를 테이블 구조와 독립적으로 만들기로 했으니 필요에 따라 컨트롤러를 마음 껏 만들면 됩니다.

그런데 이렇게 단순하게 컨트롤러와 DAO만으로 애플리케이션을 구성하다보면 여러 컨트롤러에서 공통으로 사용되는 로직이 생기게 됩니다. 물론 스프링 MVC는 컨트롤러를 일반 자바 객체(POJO)로 만들기 때문에 한 컨트롤러가 또 다른 컨트롤러를 호출하는 방식으로 구성해도 됩니다. 하지만 쉽게 애플리케이션이 복잡해지죠.

그래서 일반적으로 서비스 계층을 도입합니다.

그럼 서비스 계층은 어떤 목적을 가지고 구성하는 게 좋을까요? 아까 DAO는 테이블 구조와 연계하고 컨트롤러는 화면과 연계가 됩니다. 아마도 스토리 보드를 기획자가 만들테니 스토리 보드와 연계한다고 표현하면 되겠네요.

서비스를 구성하는 방식은 다양하겠지만 단순히 말해서 업무에 따라서 서비스를 구성하십시오. 아마도 유즈 케이스와 연계해서 구성하라고 표현하면 이해하기 쉬울 수도 있겠네요.

즉 컨트롤러-서비스-DAO을 화면-업무-테이블로 생각하고 접근하면 문제가 조금은 쉽게 풀리게 될 겁니다.

사실 서비스를 트 랜잭션 스크립을 두는 곳으로 쓰느냐 도메인 모델로 업무를 위임하는 역할만 하게 하느냐는 등의 추가 논의가 필요하지만 일단은 컨트롤러-서비스-DAO 구조를 잘 만들기만 해도 애플리케이션이 훨씬 깔끔해질 겁니다.


그럼 PointService에서 UserDAO 와 PointDAO를 이용해서
 
로직을 구현하면 된다는 말씀이신가요..?;;
 
아니면;; Service단에서 다른 Service를 이용하여 각각의 DAO에
 
접근(?)을 하도록 하여야 하는걸까요?
 
뭔가.. 답이 없는데 답을 여쭤보는거 같아 죄송스럽네요.;;;
 
그냥 서비스단을 만들어서 제 맘대로 하면 된다.........?;; 가 답일까요? ㅠ_ㅠ
 
다시한번 조언 부탁드립니다.
 
2010년 12월 16일 오후 5:36, 원상호 <shaw...@gmail.com>님 의 말:
Repository는 DAO라고 보셔도 되겠죠?

2010/12/16 원상호 <shaw...@gmail.com>

2010/12/16 나창훈 <huli...@gmail.com>

이 그룹에 게시하려면 ks...@googlegroups.com(으) 로 이메일을 보내세요.

그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에 서 그룹을 방문하세요.



--
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
* 원상호 (Won, Shawn), BPNR
* E-Mail (sh...@bpnr.co.kr, shaw...@gmail.com), Jabber ID : shaw...@gmail.com
* --- "The best way to predict the future is to invent it" - Alan Kay
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------



--
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
* 원상호 (Won, Shawn), BPNR
* E-Mail (sh...@bpnr.co.kr, shaw...@gmail.com), Jabber ID : shaw...@gmail.com
* --- "The best way to predict the future is to invent it" - Alan Kay
-----------~~-----------------~~-----------------~~------------------~~--------------------~~--------------------~~------
--
Google 그룹스 'Korea Spring User Group' 그룹에 가입했으므로 본 메일이 전송되었습니다.
이 그룹에 게시하려면 ks...@googlegroups.com(으) 로 이메일을 보내세요.

그룹에서 탈퇴하려면 ksug+uns...@googlegroups.com로 이메일을 보내주세요.
더 많은 옵션을 보려면 http://groups.google.com/group/ksug?hl=ko에 서 그룹을 방문하세요.

선영욱

unread,
Dec 16, 2010, 6:51:46 PM12/16/10
to ks...@googlegroups.com
막연하게 이럴 것이다고 느끼고 있던 내용을 다른분에게 설명을 들으니 공감도 많이 되고 맞는 방향으로 가고 있다고 자위할 수 있어서 좋았습니다.
 
앞으로 이런 글 많이 올라왔으면 좋겠습니다.
 
오늘도 좋은 하루 되세요 ^^

whites...@gmail.com

unread,
Dec 16, 2010, 7:10:34 PM12/16/10
to ks...@googlegroups.com
Application 테이블엔 어떤게 들어가는지 궁금해지지만 지금 나창훈님께서 말씀하신 시나리오를 저보고 코딩하라고하면...

사용자가 포인트를 소진하신댔죠?

User.use(Point point) 에서 로직을 구현하고 이걸 트랜잭션 처리중인 서비스쪽에서 호출해주겠네요.

간딴하죠

BlackBerry® 에서 보냈습니다.


From: 나창훈 <huli...@gmail.com>
Date: Thu, 16 Dec 2010 17:17:43 +0900
Subject: controller의 임무? DAO의 임무?
--

나창훈

unread,
Dec 16, 2010, 9:41:06 PM12/16/10
to ks...@googlegroups.com
정말 좋은 답변 감사드립니다.ㅠ_ㅠ
 
간단하게 보이면서도 간단하지가 않네요;;
 
답변을 보고 여기저기 웹서핑을 하면서
 
조금 감을 잡았습니다.^^
 
정리하면..
 
컨트롤러는 사용자 요청에 대한 결과만을 리턴하고
 
컨트롤러에서 서비스를 호출하고
 
서비스에서는 DAO들을 가지고 와서 그에 걸맞는 로직을 구현하는 식으로 하면 되는거겠죠..^^;;;;;
(자... 잘못 이해하고 있는건가;;;;;;;;;)
 
다시한번 좋은 답변 감사드립니다 꾸벅
 

Seokhoon Hyeon

unread,
Dec 16, 2010, 11:38:23 PM12/16/10
to ks...@googlegroups.com
음....

잘은 모르지만

dao 는 데이터베이스와 함께 행위를 하는 단위
service 는 트랜젝션 단위
controller는 요청과 응답의 단위

라고 이해하면 편하지 않을까요?

안 그런 경우도 있겠지만...

안 그런 경우는 뭐가 있을까요?

뭐 이미 이해하고 계신거겠죠

나의 iPhone에서 보냄

2010. 12. 16. 오후 5:17 나창훈 <huli...@gmail.com> 작성:

--
Reply all
Reply to author
Forward
0 new messages