ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [리팩토링] Controller/ Service/ DAO 책임 분배
    프로젝트/웹 ERD 프로젝트 2023. 11. 9. 16:41

    프로젝트를 진행하면서 Controller/ Service/ DAO(Data Access Object)로 나눠서 진행을 했었는데, 

    정확히 "왜 나누지?" 에 대한 궁금증을 해결하지 않고 프로젝트를 진행하다 보니 Controller에서 너무 많은 일을 하는 것 같다는 피드백이 들어왔다.

     

    Controller/ Service/ DAO 각각의 책임

    • Controller
      클라이언트의 요청을 처리하고 해당 요청에 대한 응답을 생성하는데 사용
      UI와 상호작용하고, 클라이언트에서 받은 데이터를 처리
      데이터 유효성 검사, 사용자 입력 처리, 응답생성 등의 제어흐름을 관리
    • Service
      비즈니스 로직을 구현하고 제공하는 역할
      Controller와 DAO간의 중간 레이어로 작용하여 비즈니스 로직을 추상화하고 모듈화
      데이터를 가공, 조작, 다른 서비스 레이어와 협력하여 비즈니스 요구사항을 충족
    • DAO(Data Access Object)
      데이터베이스와 상호작용하기 위한 데이터 엑세스 로직을 포함하는 역할
      데이터베이스와의 연결 및 쿼리실행을 처리, 특정 테이블 또는 엔티티와 상호작용
      데이터베이스 연동코드를 추상화하여 데이터베이스 종속성을 줄이고 코드 재사용성을 향상

    위의 내용을 바탕으로 우선 Controller에 집중되어 있는 코드들과 비즈니스 로직을들을 Service에 위임하기로 했다.

     

    MailController

    @RequestMapping(value = "/sendMailProcess", method = RequestMethod.POST)
        public String sendMail(HttpSession session, HttpServletRequest request,
                    @RequestParam("mail_file") MultipartFile multipartFile) {
    
            //사용자 정보
            MemberDTO loginDto = (MemberDTO)session.getAttribute("login");
    
            //메일 받는 사람들
            String addressListStr = request.getParameter("mail_receiver");
    
            //데이터 파싱
            String mail_title = request.getParameter("mail_title");
            String mail_content = request.getParameter("mail_content");
            String mail_sender = loginDto.getMail();
            int member_num = loginDto.getMember_num();	
    
            //Service에 넘겨줄 MailDTO
            MailDTO mailDto = new MailDTO();
            mailDto.setMail_title(mail_title);
            mailDto.setMail_content(mail_content);
            mailDto.setMail_sender(mail_sender);
            mailDto.setMember_num(member_num);
    
            String msg = service.insertMail(mailDto, addressListStr, multipartFile);
            session.setAttribute("msg", msg);	
            return "redirect:writeMail";
    	}


    MailService

    //메일 보내기
    public String insertMail(MailDTO mailDto, String addressListStr, MultipartFile multipartFile) {
        if(!multipartFile.isEmpty()) {
            saveFile(mailDto, multipartFile);
        }
        int res1 = dao.insertMail(mailDto);
    
        //최근 메일 고유번호
        int recentEmailNum = mailDto.getMail_num();
        
        //DB에 넘겨줄 MailRecDto
        MailRecDTO mailRecDto = new MailRecDTO();
        mailRecDto.setMail_num(recentEmailNum);
    
        //Mail_Rec테이블 insert (MappingTable -- 받은 사람들 저장하기)
        String msg = "메일전송이 완료되었습니다!";
        if(addressListStr != null) {
            String addressList[] = addressListStr.split(" ");
            List<Integer> rec_numList = dao.findMemberNumByEmail(addressList);
    
            int res = 0;
            for(int i=0; i<rec_numList.size(); i++) {
                mailRecDto.setRec_num(rec_numList.get(i));
                mailRecDto.setMail_receiver(addressList[i]);
                res += dao.insertReceiveTable(mailRecDto); //insert 작업
            }
    
            if(res != rec_numList.size()) {
                msg = "다시 시도해주세요";
                return "redirect:writeMail";
            }
        } 
        //내게쓰기인 경우
        else if(addressListStr == null) {
            mailRecDto.setRec_num(mailDto.getMember_num());
            mailRecDto.setMail_receiver(mailDto.getMail_sender());
            dao.insertReceiveTable(mailRecDto); //insert 작업
        }
        return msg;
    }

     

    이런식으로 Controller에는 Http요청과 HttpSession의 데이터 관리만 하고 
    데이터들을 Service에 넘겨준 뒤 Service에서 비즈니스 로직들을 처리하도록 했다.

     

    확실히 가독성이 많이 올라가고, 결합성이 줄어들어 유지보수가 쉬울 것 같다는 생각이 들었다.
    그리고 이전의 코드는 메일쓰기와 내게 메일쓰기의 비즈니스 로직이 따로 처리가 되었지만,
    가독성이 높아지면서 합쳐놔도 큰 문제가 생기지 않는다는 것을 알게되어 코드의 효율성도 올릴 수 있었다.  

Designed by Tistory.