
스프링 1일차에서 다음과 같은 코드를 가져와보자.
package com.springbook.biz.board; import java.util.List; public interface BoardService { //CRUD 기능의 메소드 구현 //글 등록 void insertBoard(BoardVO vo); //글 수정 void updateBoard(BoardVO vo); //글 삭제 void deleteBoard(BoardVO vo); //글 상세 조회 BoardVO getBoard(BoardVO vo); //글 목록 조회 List<BoardVO> getBoardList(BoardVO vo); }
package com.springbook.biz.board.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.springbook.biz.board.BoardService; import com.springbook.biz.board.BoardVO; @Service("boardService") /* * Service 클래스는 jsp/servlet할 때 안 배웠음 * 업무로직 처리를 담당하는 클래스 * ex) 계좌이체 기능 처리할 때 DB입력은 DAO에서 하게 되는데 * DB 입력 전에 필요한 작업들(계좌 암호화, 금액 컴마 추가...) 하는 로직들을 ServiceImpl클래스에서 처리해주면 됨 * */ public class BoardServiceImpl implements BoardService{ @Autowired BoardDAO boardDAO; public void insertBoard(BoardVO vo) { boardDAO.insertBoard(vo); } public void updateBoard(BoardVO vo) { boardDAO.updateBoard(vo); } public void deleteBoard(BoardVO vo) { boardDAO.deleteBoard(vo); } public BoardVO getBoard(BoardVO vo) { return boardDAO.getBoard(vo); } public List<BoardVO> getBoardList(BoardVO vo) { return boardDAO.getBoardList(vo); } }

현재까지의 다이어그램을 그려보면 다음과 같다.
그런데 만약 다음과 같은 코드를 쓰면 어떨까?
public class BoardServiceImpl implements BoardService{ @Autowired BoardDAO boardDAO; @Autowired JDBCBoardDAO jdbcboardDAO; public void insertBoard(BoardVO vo) { boardDAO.insertBoard(vo); } public void updateBoard(BoardVO vo) { boardDAO.updateBoard(vo); } public void deleteBoard(BoardVO vo) { boardDAO.deleteBoard(vo); } public BoardVO getBoard(BoardVO vo) { return boardDAO.getBoard(vo); } public List<BoardVO> getBoardList(BoardVO vo) { return boardDAO.getBoardList(vo); } public void jdbcinsertBoard(BoardVO vo) { jdbcboardDAO.insertBoard(vo); } public void jdbcupdateBoard(BoardVO vo) { jdbcboardDAO.updateBoard(vo); } public void jdbcdeleteBoard(BoardVO vo) { jdbcboardDAO.deleteBoard(vo); } public BoardVO jdbcgetBoard(BoardVO vo) { return jdbcboardDAO.getBoard(vo); } public List<BoardVO> jdbcgetBoardList(BoardVO vo) { return jdbcboardDAO.getBoardList(vo); } }
여기서 Tight Coupling의 문제가 발생하게 되는데 이것이 무엇이 문제일까??
유지보수 어려움: BoardServiceImpl은 두 DAO 객체와 밀접하게 연결되어 있으므로, 하나의 DAO 객체를 변경하면 BoardServiceImpl의 코드를 수정해야 합니다. 이는 유지보수에 어려움을 줄 수 있습니다.
(예를 들어 Autowired가 된 DAO 객체가 수백개가 된다 치자.
그걸 일일이 찾아가서 메소드와 변수를 일일이 고치는건 찾는데 있어서 아주 시간낭비일것이다.)
테스트 어려움: 테스트할 때도 BoardServiceImpl의 코드가 JDBCBoardDAO에 의존하므로, JDBCBoardDAO의 동작에 따라 테스트가 영향을 받을 수 있습니다.
특히 JDBCBoardDAO가 데이터베이스와 직접 상호작용하면, 테스트를 수행하기 어려워집니다.
(예를 들어 jdbcboardDAO에서 만약에 문제가 생겨서 수정을 해야할 상황이 온다 치자. 그러면 BoardServiceImpl에서도 문제가 발생할 확률이 매우 높다. 아무 상관없는 boardDAO 빈 객체만 불쌍할 뿐이다.)
확장성 제한: 또 다른 DAO 구현체를 사용하고자 할 때도 BoardServiceImpl의 코드를 수정해야 합니다. 이로 인해 새로운 DAO 구현체와의 결합도가 높아져서 애플리케이션의 확장성이 제한될 수 있습니다.
(예를 들어 JDBCBoardDAO를 JPADAO로 바꾼다 치자.
그러면 JDBCBoardDAO를 찾아가서 일일이 JDBCBoadrDAO를 JPADAO로 다 바꾸어야 한다. 이것은 너무 귀찮다.)
그러니까 우리는 BoardService를 구현한 JDBCBoardServiceDAO를 따로 두는것이 가장 이상적이다.
