2020 11 27
2020 11 30 업데이트
개발을 하다 보면 외부 라이브러리를 사용해야 할 때가 수도 없이 많이 생긴다. 하지만 그 라이브러리가 Deprecated 되거나, 다른 라이브러리로 교체해야 하는 일이 생기면 어떻게 될까? 극단적으로 코드 처음부터 하나하나 뜯어 고쳐야 할 수도 있다.
이럴 경우, 외부 라이브러리를 가지고, 외부에서 호출할 수 있게 인터페이스를 제공해주는 DI, 즉 Dependency Injection(의존성 주입)하는 것을 만드는 것이다.
Javascript나 JAVA 등여러 다른 언어에서 의존성 분리를 사용하지만 최근에 배웠던 Swift언어로 의존성 분리를 공부해보았다.
class A{
var anum: Int = 1
}
class B{
var bNum = A()
}
let b = B()
print(b.bNum.aNum)
B 클래스에서 A클래스를 내부에 변수로 사용하게 되므로
B 클래스는 A 클래스에 의존관계가 생기게 된다.
class B{
var bNum: Int
init(num : Int){
self.bNum = num
}
func setBNum(num: Int){
self.bNum = num
}
}
let b = B(Int(3)) // 외부에서 객체 생성
print(b.bNum)
b.setBNum(Int(5)) // 객체 생성
Int(3), Int(5)를 생성해서 함수로 넣어줌.
-> 이렇게 객체를 외부에서 생성해서 클래스 안에 넣어주는 것을 주입 한다고 말한다.
내부에서 만든 변수를 외부에서 넣어주면 된다.
class A{
var aNum: Int = 1
}
class B{
var bNum: A
init(num: A){
self.bNum = num
}
}
let b = B(A())
B 클래스 내부변수로 A 클래스를 사용하고, 이 A 클래스를 외부에서 생성해서 B에 주입해준다.
하지만 위의 코드를 의존성 주입이라고 말하지는 않는다.
첫째, 상위 모듈은 하위 모듈에 의존해서는 안된다. 상위 모듈과 하위 모듈 모두 추상화에 의존해야 한다.
둘째, 추상화는 세부 사항에 의존해서는 안된다. 세부사항이 추상화에 의존해야 한다.
상위 모듈이 하위 모듈에 의존해서는 안되기 때문에, 이것을 반전시킨다. 대부분의 언어는 interface이고 Swift는 protocol을 사용한다.
protocol DIInterface: AnyObject{
var num: Int{get set}
}
class A: DIInterface{
var aNum = 1
}
class B{
var bNum: DIInterface
init(num: DIInterface){
self.bNum = num
}
}
let b = B(A())
프로그래머가 작성한 프로그램이, 라이브러리의 흐름 제어를 받게 되는 디자인 패턴
상속을 통해서가 아닌, 인터페이스 프로토콜에 따라 사용자가 정의한 메소드를 프레임워크의 동작을 변경하는데 사용함.
자바 코드의 블랙박스 프레임워크
new Thread(new Runnable() {
@Override
public void run() {
// Do something
}
}).start();
IoC는 사용자가 구현한 인터페이스를 의존하는 하위 모듈로 참조하든 말든 상관하지 않는다. 하지만 DI는 의존관계에 대한 것이기 때문에 하위 모듈은 상위 모듈의 has 관계가 되어야 한다.
IoC를 구현하는 프레임워크로 객체를 관리, 생성을 책임지고 의존성을 관리하는 컨테이너
모든 의존성을 Container를 통해 받아오게 됨
https://javaslave.tistory.com/11
에서 Hellow World 를 통한
요구조건 만족을 위한 좋은 설명이 있어서 넣어보았다.