2012. 2. 22.

IoC/DI 의 활용

* 본 post는 [토비의 스프링3]에서 발췌한 것이다

*  DI를 이용한 핵심기능의 변경

디자인 패턴의 전략패턴에 해당하는 의존 대상의 implementation 의 변경에 사용함.
A->B 에서 A 기능 일부를 B에게 위임하는 경우 필요에 따라 B의 구현방식을 통째로 B1, B2, B3로 변경한다.
ex) DAO의 구현을 JDBC, JPA, Hibernate, JDO, iBatis 등으로 변경
ex) 사용자 등급 결정 정책을 DI로 새오운 클래스로 변경


* 핵심기능의 동적인 변경

DI 도 runtime 시에 동적으로 의존 Object 를 연결해 주긴 하지만, DI되면 정적인 관계가 형성된다. 하지만 DI 를 잘 이용하면, 애플리케이션이 동작하는 중간에 의존 대상을 dynamic 하게 변경할 수 있다.
ex)사용자 등급에 따른 DataSource의 선택
DAO->DataSource 일때, DAO 하나가 여러개의 DataSource 에 의존하게 만들어, 현재 접속한 사용자의 등급에 따라서 다른 DataSource 를 DAO가 사용하도록 한다.
ex) 사용자 별로 독립 Object 만들고 서비스 Object가 이를 DI 받아서 사용하는 경우.


* 부가기능의 추가

DI의 다른 활용방법은 핵심기능은 그대로 두고 부가기능을 추가하는 것이다. Decoration Pattern 의 경우임.
ex) 트랙잭션 기능 부여.
핵심 기능은 그대로 두고 결과나 전달 파라미터를 조작할 수 있고, 파라미터나 리턴 결과를 활용해 로깅이나 보안처리 같은 부가적인 작업을 수행 할 수도 있다. 이베트 발생 처리 등등.


* 인터페이스의 변경

클라이언트가 사용하는 실제 인터페이스와 실제 오브젝트 사이의 인터페이스가 일치하지 않는 경우에도 DI 는 유용하다. A->B인터페이스 고, C는 B인터페이스를 구현하지 않았더라도 A가 DI를 통해 B를 사용하므로, B의 구현 오브젝트에서 C를 호출해 주는 어댑터 처럼 동작하면 된다.
PSA (Portable Service Abstraction): 이를 좀 더 일반화 하여 아예 인터페이스가 다른 다양한 구현을 같은 방식으로 사용하도록, 중간에 인터페이스 어댑터 역할을 해주는 레이어를 하나 추가하는 방법이다.

 
* 프록시

laze loading(필요한 시점에서 실제 사용할 오브젝트를 초기화, 준비) 할때, 또는 원격 오브젝트를 호출할 때 마치 로컬에 존재하는 오브젝트 처럼 사용할 수 있도록 할때 프록시가 필요하고, 이 경우 DI를 필요로 한다. Spring이 지원하는 리모트 기술은 EJB원격호출, 웹 서비스, REST, HTTP 등 다양하다.


* 템플릿과 콜백

템플릿/콜백 패턴은 DI의 특별한 적용방법이다. 반복적으로 등장하지만, 항상 고정적인 작업 흐름과 그 사이에서 자주 바뀌는 부분은 분리해서 템플릿과 콜백으로 만들고 DI원리를 응용해 적용한다. Spring 이 기본으로 제공하는 20여가지의  템플릿/콜백외에도 직접 응용할 수 있어야 한다.


* Singleton 과 Object Scope

DI를 프레임워크로 이용한다는건 DI대상 오프젝트를 컨터이너가 관리한다는 의미이다. 오브젝트의 생성부터 관계설정, 이용, 소멸에 이르기까지 모든 과정을 DI컨테이너가 주관하기 때문에, 그 오브젝트의 스코프를 자유롭게 제어할 수 있다. 스프링의 DI는 기본적으로 singleton으로 오브젝트를 만들어서 사용하게 하고, 컨테이너가 알아서 싱글톤을 만들고 관리하므로 클레스 자체는 싱글톤을 고려하지 않아도 된다. 물론, 스프링에서는 싱글톤 외에도 다양한 스코프를 갖는 오브젝트를 만들어 DI 할 수 있다.


* 테스트

DI의 또다른 중요한 용도는 Test 이다.테스트 할 대상이 사용하는 오브젝트를 테스트 목적으로 만들어진 Mock 오브젝트로 대체하면 테스트가 매우 용이하다.

댓글 없음:

댓글 쓰기