느슨한 결합력
Service: 사용자의 요구사항이 담기는 곳
Dao: 자바를 사용해서 Service에서 요청하는 요구사항을 전달함 (데이터베이스에 접근하여)
- 시나리오
- 사용자가 요구사항 전달함
- Service가 딱 보니 Dao1로 해결가능
- Dao1이 DB에 접근하여 데이터를 가져와서 Service에 전달
- Service는 사용자에게 전달
- 사용자가 받은 후 아... 이거 조금 바꿔달라 요구함
- Service는 Dao2를 생성 후 다시 사용자에게 전달
- 사용자가 다시 수정해달라함
- 반복...
수정하는 방법엔 두 가지가 존재한다.
- dao1코드를 수정
- dao1은 그대로 두고 dao2를 생성
1번 방식은 다시 dao1이 필요한 경우 다시 수정을 해야한다
2번 방식은 service는 dao1을 가리키고 있기 때문에 service가 dao2를 가리키도록 수정해야한다
즉 service와 dao1은 결합력이 높은 상태. 우리가 원하는 것은 dao1을 바꿔도 service코드는 수정 안해도되는 상태를 바람. 이것이 느슨한 결합력인 상태
HOW??
service는 dao1 dao2로 지정해서 지목하지 말고 뭉뚱그려서 dao만 가리키게함
private dao1 d = new dao1(); ( X )
private dao d = new dao1(); ( O )
어떻게 dao1을 안가리키고 dao을 지목했는데 에러가 발생하지 않지??
인터페이스 때문!
service → dao1에서
service → dao(인터페이스) → dao1로 변경됨
휴대폰 USB충전 케이블과 어댑터 예를 들면 이해하기 쉽다.
휴대폰 단자 타입은 여러가지다(5핀, c타입, (구)안드로이드) 단자와 어댑터 일체형이 아니라 어댑터는 usb방식으로 통일하고 단자는 usb로 통일한 뒤 뒤에부분만 휴대폰에 맞는 선으로 변경한 제품이 많다. 여기서 USB를 인터페이스라고 이해하면 편하다.
즉 어댑터 -> 휴대폰에서 어댑터 -> USB -> 휴대폰으로 중간 통로를 하나 만들어서 향후 휴대폰 단자가 변경된다면 중간에 있는 선만 변경하면 된다. (후에 언급되는 DI에 비유해도 된다.)
어 근데 dao로 구현하는건 좋은데 new dao1();을 입력하는 것도 귀찮은데....
이를 해결하기 위해 dao1이라고 직접 코드를 입력하지 않고 XML이나 Annotation을 통해서 외부 파일에서 미리 설정을해서 dao1을 입력 안해도 가능
DI
직역하자면 의존성 주입이다. 직역으로는 무슨 의미인지 도통 모르겠다.
노트북과 데스크탑의 예로 들어보자
노트북은 부품 수정이 불가능하다(그렇다고 치자) 반면 데스크탑은 부품 수정이 가능하다.
노트북은 조립할 필요가 없고 데스크탑은 조립을 해야한다. 언뜻 보면 노트북이 좋을 것 같지만 우리 모두는 데스크탑의 장점을 안다.
바로 조립이다.
새로운 그래픽카드, CPU가 출시하면 노트북은 갈아끼울 수 없지만 데스크탑은 가능하다. 조립해야 하는 불편함은 있지만 갈아 끼울 수 있다는 큰 장점이 된다.
프로그래밍도 비슷하다.
a클래스가 b클래스를 이용하는경우 new a();로 생성하면 자동적으로 b도 생성되는 것이 노트북이다.
A.class
private B b;
public void A(){
b = new B();
}
이런식으로 A를 생성하면 자동적으로 b가 생성되게 구현된 것이 노트북이다.
A.class
private B b;
public void setB(B b){
this.b = b;
}
이렇게 setB로 조립하는 것이 데스크탑이다
set B()를 호출해야 b가 a안에 주입되는 것을 의존성 주입이라고 한다. 물론 setB가 아니라 생성자를 통해서 주입하기도 한다.
DI를 사용하는 이유는 노트북과 데스크탑의 예와 비슷하다. 프로그래밍은 수정이 빈번하기 때문에 부품을 자주 교체해야한다. 그래서 일체형인 노트북보다 조립형인 데스크탑방식을 선호하게 된다.
앞서 언급한 USB와 충전 케이블의 예도 이곳에 적용된다.
참조: 뉴렉처님 유튜브