Tech Blog of Pinomaker

DI

Dependency Injection의 약자로, 의존 주입을 의미하는 데, 여기서 말하는 의존이란 객체 간의 의존을 의미한다. 아래의 예시를 보고 알아보자.

 

public class MemberService{
  // MemberDao 객체 생성
  private MemberDao memberDao = new MemberDao();
  
  // Member 저장 메서드
  public void save(RequestDto req){
    // 같은 Email의 Member가 있는 지 조회
    Member member = memberDao.selectByEmail(req.getEamil());
    
    // Email을 가진 Member가 있으면 예외 처리
    if(member != null){
      throw new DuplicateMemberException("DUP EMAIL");
    }
   
    Member newMember = new Member(req.getEmail(), req.getPassword());
    memberDao.save(newMember);
  }
}

 

위의 예시를 보면 먼저 MemberService는 MemberDao의 객체 memberDao를 생성하고, Member를 저장하는 save 메서드를 가지고 있는 데, 메서드는 사용자가 입력한 데이터 Email과 Password를 매개 변수로 받게 된다.

 

먼저 Email 중복 방지를 위한 조회 및 예외 처리를 진행하고, 중복이 없을 경우 생성자를 이용하여 newMember 객체를 생성한 후 memberDao의 메서드 save()를 이용하여 저장을 하는 코드다.

 

여기서 볼 부분은 MemberService 클래스가 데이터 처리를 위하여 MemberDao 클래스의 메서드를 사용한다. 우리의 코드를 보면 위에서 말한 것처럼 중복 방지 코드를 작성 후, MemberDao의 selectByEmail()를 실행하고, save()를 사용했다.

 

이렇게 한 클래스가 다른 클래스의 메서드를 실행할 때 의존한다고 하며, 위의 예시는 MemberService 클래스가 MemberDao 클래스에 의존한다고 할 수 있다.

 

 

의존하는 대상이 있으면 그 대상을 구하는 방법이 필요한데, 가장 쉬운 방법은 의존 대상의 객체를 직접 생성하는 것이며 위의 예제에서도 MemberService 클래스가 MemberDao의 객체를 직접 생성해서 필드에 할당 하였다.

 

클래스 내부에서 직접 의존 객체를 생성하는 것이 쉽지만 유지 보수의 관점에서는 문제를 유발 할 수 있으며, 이를 해결하기 위한 방법이 DI와 서비스 로케이터다.

 

DI는 의존하는 객체를 직접 생성한느 것이 아니라 의존 객체를 전달 받아서 사용하는 데, 아래의 예시를 보자.

 

public class MemberService{
  private MemberDao memberDao;
  
  public class MemberService(MemberDao memberDao){
    this.memberDao = memberDao
  }
  
  // Member 저장 메서드
  public void save(RequestDto req){
    // 같은 Email의 Member가 있는 지 조회
    Member member = memberDao.selectByEmail(req.getEamil());
    
    // Email을 가진 Member가 있으면 예외 처리
    if(member != null){
      throw new DuplicateMemberException("DUP EMAIL");
    }
   
    Member newMember = new Member(req.getEmail(), req.getPassword());
    memberDao.save(newMember);
  }
}

 

직접 의존 객체를 생성했던 코드와 달리 의존 객체를 직접 생성하지 않고 생성자를 통하여 의존 객체를 전달 받는 데, 이는 생성자를 통해 MemberService가 의존하고 있는 MemberDao 객체를 주입 받은 것이다. 의존 객체를 직접 구하지 않고 생성자를 통해 전달 받기에 DI 패턴을 따르고 있는 것이다.

 

DI, 의존 객체 변경의 유연함

 

의존 객체를 직접 생성하는 방식은 필드나 생성자에서 new 키워드를 이용해서 객체를 생성해야한다. 그렇다면 만약에 기존에 사용하던 MemberDao가 아니라 MemberDaoSql 클래스를 주입 받아야한다면 모든 코드를 수정해야하는 변경해야하는 번거로움이 생긴다.

 

하지만 의존 객체를 생성자를 통하여 주입 받도록 구현하면, MemberDaoSql 클래스를 사용하게 된다고 하더라도 memberDaoSql의 객체를 생성하는 코드로만 변경을 하면 되는 용이함이 있다.

profile

Tech Blog of Pinomaker

@pinomaker

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!