제어의 역전(IoC)이란 뭘까?
- 외부의 API에서 실행 되어야 하는 작업을 사용자(프로그래머)에게 넘기는 것
사실 이미 잘 하고 있다. 다만, 이게 제어의 역전인지 모를 뿐..
filter라는 메서드를 구현한다고 했을 때, 아래와 같이 구현을 해본다고 하자.
function filter(array) {
let newArray = []
for (let index = 0; index < array.length; index++) {
const element = array[index]
if (element !== null && element !== undefined) {
newArray[newArray.length] = element
}
}
return newArray
}
// 사용처
filter([0, 1, undefined, 2, null, 3, 'four', ''])
만약 위의 코드에서 0만 필터링 해주는 기능을 추가한다고 하면 어떨까?
filter 메서드에 매개변수를 추가하고, 내부의 분기문을 하나 더 추가하고 하며 점점 더 filter 함수가 비대해진다. 이렇게 비대해지는 함수는 유지보수에 취약하다.
제어의 역전 사용해보기
function filter(array, filterFn) {
let newArray = []
for (let index = 0; index < array.length; index++) {
const element = array[index]
if (filterFn(element)) {
newArray[newArray.length] = element
}
}
return newArray
}
filter(
[0, 1, undefined, 2, null, 3, 'four', ''],
el => el !== null && el !== undefined
)
위와 같이 구현하게 된다면 filter 함수는 여러 요구사항에 맞춰서 대응될 필요가 없다.
즉 필터링하는 책임을 filter메서드에서 제어하는게 아니라, 사용처에 위임한 것이다. 그래서 제어의 역전이다.
- 리액트에서 컴파운드 컴포넌트 역시 제어의 역전의 예시이다.
- 컴파운드 컴포넌트 패턴 역시 하나의 컴포넌트에서 모든 책임을 제어하는게 아니라, 외부에 책임을 위임시켜버림으로써 많은 유즈케이스에 대응 할 수 있다.
그렇다고 무조건 제어의 역전이 정답일까?
언제나 그렇듯 과한 추상화는 경계하자. 유즈케이스가 많아질 때 추상화를 해도 늦지 않다.