DI (의존성 주입) 의 이해

조성현·2022년 12월 13일
0

강한 결합

  • 이해를 위한 예제
  1. Contoller1Service1 객체를 생성하여 사용
      public class Controller1 {
      	private final Service1 service1;
      
      	public Controller1() {
      		this.service1 = new Service1();
      	}
      }
  2. Service1Repostiroy1 객체를 생성하여 사용
      public class Service1 {
      	private final Repository1 repository1;
      
      	public Service1() {
      		this.repository1 = new Repository1();
      	  }
        }
  3. Repostiroy1 객체 선언
      public class Repository1 { ... }
  4. 만약, 다음과 같이 변경된다면..
    1. Repository1 객체 생성 시 DB 접속 id, pw 를 받아서 DB 접속 시 사용
    - 생성자에 DB 접속 id, pw 를 추가
     public class Repository1 { 
         public Repository1(String id, String pw) {
           // DB 연결
           Connection connection = DriverManager.getConnection("jdbc:h2:mem:db", id, pw);
             }
           }

강한 결합의 문제점
1. Controller 5 개가 각각 Service1 을 생성하여 사용 중
2. Repository1 생성자 변경이 발생 시
모든 Contoller모든 Service 의 코드 변경이 필요


강한 결합 해결방법

그렇다면 강한 결합을 해결할 방법이 없을까?
1. 각 객체에 대한 객체 생성은 딱 1번만!
2. 생성된 객체를 모든 곳에서 재사용!

  1. Repository1 클래스 선언 및 객체 생성repository1

  2. Service1 클래스 선언 및 객체 생성 (repostiroy1 사용)service1

    Class Service1 {
    	private final Repository1 repitory1;
    
    	// repository1 객체 사용
    	public Service1(Repository1 repository1) {
    		~~this.repository1 = new Repository1();~~
    		this.repository1 = repository1;
    	}
    }
    
    // 객체 생성
    **Service1 service1 = new Service1(repository1);**

  1. Contoller1 선언 ( service1 사용)

    Class Controller1 {
    	private final Service1 service1;
    
    	// service1 객체 사용
    	public Controller1(Service1 service1) {
    		~~this.service1 = new Service1();~~
    		this.service1 = service1;
    	}
    }
  2. 만약, 다음과 같이 변경된다면,

  • Repository1 객체 생성 시 DB 접속 id, pw 를 받아서 DB 접속 시 사용
    - 생성자에 DB 접속 id, pw 를 추가
    public class Repository1 {
        
      public Repository1(**String id, String pw**) {
      // DB 연결
       Connection connection = DriverManager.getConnection("jdbc:h2:mem:db", id, pw);
         }
       }
       
       // 객체 생성
       String id = "sa";
       String pw = "";
       Repository1 repository1 = new Repository1(**id, pw**);

개선 결과
Repository1 생성자 변경은 이제 누구에게도 피해(?) 를 주지 않음
Service1 생성자가 변경되면? 모든 Contoller → Controller 변경 필요 X

강한 결합이 느슨한 결합으로 바뀜!


제어의 역전 (IoC: Inversion of Control)

  • 프로그램의 제어 흐름이 뒤바뀜

일반적인 과정: 사용자가 자신이 필요한 객체를 생성해서 사용

이와 반대의 접근 -> IoC (제어의 역전) / 이를 통해 '느슨한 결합'으로 변환가능!

  • 용도에 맞게 필요한 객체를 그냥 가져다 사용하는 것
    이를 DI (Dependency Injection)" 혹은 한국말로 "의존성 주입"이라고 부릅니다.
  • 사용할 객체가 어떻게 만들어졌는지는 알 필요 없음

  • 실생활 예제) 가위의 용도별 사용

    • 음식을 자를 때 필요한 가위는? → 부엌가위 (생성되어 있는 객체 kitchenScissors)
    • 무늬를 내며 자를 때 필요한 가위는? → 핑킹가위 (생성되어 있는 객체 pinkingShears)
profile
맛있는 음식과 여행을 좋아하는 당당한 뚱땡이

0개의 댓글