스프링 DI와 다형성

Lucy in the Sky with Diamond·2023년 8월 4일

스프링 정리

목록 보기
4/5
post-thumbnail

Tight Coupling & Loose Coupling

스프링 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를 따로 두는것이 가장 이상적이다.

0개의 댓글