맨위로가기

제어 반전

"오늘의AI위키"는 AI 기술로 일관성 있고 체계적인 최신 지식을 제공하는 혁신 플랫폼입니다.
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.

1. 개요

제어 반전은 프로그램의 제어 흐름을 프레임워크나 컨테이너가 관리하도록 하는 프로그래밍 원칙으로, 1970년대부터 개념이 존재해왔다. 객체 지향 프로그래밍의 발전과 함께 널리 사용되었으며, 의존성 주입을 통해 구현되는 경우가 많다. 스프링 프레임워크와 같은 기술을 통해 한국 IT 산업에도 큰 영향을 미쳤으며, 코드 결합도를 낮추고 유연성을 높이는 데 기여하지만, 복잡성을 증가시키고 런타임 오류의 가능성을 높일 수 있다는 비판도 있다.

더 읽어볼만한 페이지

  • 컴포넌트 기반 소프트웨어 공학 - 컴포넌트 오브젝트 모델
    컴포넌트 오브젝트 모델(COM)은 마이크로소프트에서 개발한 소프트웨어 컴포넌트 기술로, 서로 다른 애플리케이션이 객체를 통해 통신하고 기능을 공유할 수 있도록 하는 이진 인터페이스 표준을 제공하며, 다양한 프로그래밍 언어로 작성된 객체들의 상호 운용을 지원한다.
  • 컴포넌트 기반 소프트웨어 공학 - 공통 객체 요구 매개자 구조
    공통 객체 요구 매개자 구조(CORBA)는 객체 관리 그룹(OMG)에서 분산 컴퓨팅 환경에서 객체 지향 기술을 통합하기 위해 제정한 표준 아키텍처로서, 객체 요청 브로커(ORB)를 통해 객체 간 통신을 제공하고 다양한 서비스를 지원한다.
  • 아키텍처 패턴 - 서비스 지향 아키텍처
    서비스 지향 아키텍처(SOA)는 기능들을 독립적인 서비스 단위로 분리하여 느슨하게 결합함으로써, 네트워크를 통해 접근 가능한 서비스를 재사용하고 결합하여 응용 프로그램을 구축하는 소프트웨어 아키텍처이다.
  • 아키텍처 패턴 - 데이터 접근 객체
    데이터 접근 객체(DAO)는 애플리케이션의 비즈니스 로직과 데이터 접근 로직을 분리하여 유지보수성과 유연성을 높이는 디자인 패턴으로, 데이터 저장소 접근을 위한 추상화 계층을 제공하며 다양한 도구와 프레임워크를 통해 구현된다.
  • 소프트웨어 디자인 패턴 - 모델-뷰-컨트롤러
    모델-뷰-컨트롤러(MVC)는 소프트웨어 디자인 패턴으로, 응용 프로그램을 모델, 뷰, 컨트롤러 세 가지 요소로 분리하여 개발하며, 사용자 인터페이스 개발에서 데이터, 표현 방식, 사용자 입력 처리를 분리해 유지보수성과 확장성을 높이는 데 기여한다.
  • 소프트웨어 디자인 패턴 - 스케줄링 (컴퓨팅)
    스케줄링은 운영 체제가 시스템의 목적과 환경에 맞춰 작업을 관리하는 기법으로, 장기, 중기, 단기 스케줄러를 통해 프로세스를 선택하며, CPU 사용률, 처리량 등을 기준으로 평가하고, FCFS, SJF, RR 등의 알고리즘을 사용한다.
제어 반전

2. 역사적 배경

제어 반전(IoC)은 컴퓨터 과학에서 새로운 개념은 아니며, 1970년대 마이클 A. 잭슨의 잭슨 구조적 프로그래밍 방법론에서 설명된 '프로그램 반전' 개념과 관련이 있다.[7] 마틴 파울러는 이 용어의 어원을 1988년으로 거슬러 올라간다고 보았다.[6]

이 용어는 Michael Mattsson의 논문에서 사용되었고,[8] 이후 Stefano Mazzocchi가 1999년 아파치 소프트웨어 재단의 Avalon 프로젝트에서 대중화했다.[9] 2004년에는 로버트 C. 마틴과 마틴 파울러에 의해 더욱 널리 알려졌다.[6]

Java와 같은 새로운 프로그래밍 환경이 널리 사용되면서 IoC라는 용어가 널리 퍼지게 되었고, 개발자들은 설계 원칙의 중요성을 재인식하게 되었다. 제어 반전은 의존성 주입과 밀접하게 관련되어 있으며, 의존성 주입은 제어 반전을 실현하는 유효한 방법 중 하나이다.

2. 1. 초기 개념

제어 반전은 컴퓨터 과학에서 새로운 용어가 아니다. 마틴 파울러는 이 용어의 어원을 1988년으로 거슬러 올라간다고 보았지만,[6] 이는 1970년대 마이클 A. 잭슨이 그의 잭슨 구조적 프로그래밍 방법론에서 설명한 '''프로그램 반전''' 개념과 밀접하게 관련되어 있다.[7] 상향식 파싱은 하향식 파싱의 반전으로 볼 수 있는데, 한쪽에서는 제어가 파서에 있고 다른 쪽에서는 제어가 수신 애플리케이션에 있다.

이 용어는 Michael Mattsson이 논문에서 사용했으며(프레임워크가 반대로 애플리케이션 코드를 호출하는 원래 의미로),[8] 이후 Stefano Mazzocchi가 이를 가져와[9] 1999년 폐지된 아파치 소프트웨어 재단 프로젝트인 Avalon에서 대중화했다. Avalon에서는 상위 객체가 실행 흐름을 제어하는 것 외에도 하위 객체의 종속성을 전달하는 것을 의미했다.[10]

2. 2. 객체 지향 프로그래밍과의 결합

마틴 파울러는 제어 반전(Inversion of Control, IoC)이라는 용어가 1988년으로 거슬러 올라간다고 보았지만,[6] 1970년대 마이클 A. 잭슨의 잭슨 구조적 프로그래밍 방법론에서 설명한 '프로그램 반전' 개념과 관련이 있다.[7] 21세기에 들어와 IoC라는 약칭과 함께 널리 퍼지게 된 데에는 Java 등 새로운 환경이 널리 사용되면서 해당 프로그래머도 늘어났다는 배경이 있으며, 이는 그러한 설계 원칙에 개발자들의 시선을 끌어당겨 그 중요성을 재인식하게 했다.

이 용어는 Michael Mattsson이 논문에서 사용했으며(프레임워크가 반대로 애플리케이션 코드를 호출하는 원래 의미로),[8] 이후 Stefano Mazzocchi가 이를 가져와[9] 1999년 폐지된 아파치 소프트웨어 재단 프로젝트인 Avalon에서 대중화했다. 2004년 로버트 C. 마틴과 마틴 파울러에 의해 더욱 대중화되었다.[6]

제어 반전은 의존성 주입과 밀접하게 관련되어 있으며, 의존성 주입은 제어 반전을 실현하는 유효한 방법 중 하나이다.

3. 제어 반전의 원리

제어 반전(Inversion of Control, IoC)은 프로그램의 제어 흐름을 개발자가 직접 작성하는 대신, 소프트웨어 프레임워크나 컨테이너가 관리하도록 하는 원칙이다.[11]

전통적인 프로그래밍에서는 비즈니스 로직흐름이 서로 정적 결합된 객체에 의해 결정되지만, IoC를 사용하면 프로그램 실행 중에 만들어지는 객체 그래프에 따라 흐름이 결정된다.[14] 이러한 동적인 흐름은 추상화를 통해 정의된 객체 상호작용으로 가능해진다.

IoC는 코드 간의 결합도를 낮추고 유연성과 재사용성을 높이는 데 기여한다. 예를 들어, `ServerFacade` 클래스가 특정 `DAO` 객체에 직접 의존하는 대신, `DAO` 인터페이스에 의존하고 실제 구현은 외부에서 주입받도록 설계할 수 있다.

```java

public class ServerFacade

{

public Object respondToRequest(Object pRequest, DAO dao)

{

return dao.getData(pRequest);

}

}

```

위 코드에서 `respondToRequest` 메서드는 `DAO` 객체를 인자로 받아 `getData` 메서드를 호출하며, 실제 어떤 `DAO` 구현체가 사용될지는 외부에서 결정된다.

이러한 지연 바인딩은 의존성 주입이나 서비스 로케이터 패턴과 같은 메커니즘을 통해 구현할 수 있다.[4] "제어 반전"이라는 용어는 의존성 주입 패턴을 지칭하는 데에도 사용되는데, 이는 스프링 프레임워크와 같은 자바 프레임워크의 "IoC 컨테이너"에서 흔히 볼 수 있다.[4]

IoC는 "할리우드 원칙: 우리에게 전화하지 마세요. 저희가 전화드리겠습니다"라고도 불린다.[1]

3. 1. 전통적인 프로그래밍 방식과의 비교

전통적인 프로그래밍에서는 개발자가 작성한 코드가 라이브러리의 함수를 호출하는 방식으로 동작한다.[5] 예를 들어, 애플리케이션의 main 함수는 메뉴 라이브러리의 함수를 호출하여 사용 가능한 명령 목록을 표시하고, 사용자가 그 중 하나를 선택하도록 한다.[14] 그러면 라이브러리는 사용자가 선택한 항목을 함수 호출의 반환 값으로 돌려주고, main 함수는 이 값을 사용하여 관련 명령을 실행한다. 이러한 방식은 텍스트 사용자 인터페이스에서 흔히 볼 수 있다. 예를 들어, 이메일 클라이언트는 "새 메일 읽기", "이 메일에 답장하기", "새 메일 작성" 등의 명령어가 있는 화면을 표시하고, 사용자가 명령을 선택할 때까지 프로그램 실행을 멈춘다.

반면, 제어 반전에서는 프로그램이 소프트웨어 프레임워크를 사용하여 작성된다. 이 프레임워크는 윈도우 시스템, 메뉴, 마우스 제어 등과 같은 일반적인 동작 및 그래픽 요소를 알고 있다. 사용자 지정 코드는 메뉴 항목 테이블을 제공하고 각 항목에 대한 코드 서브루틴을 등록하는 등 프레임워크에 "빈칸을 채우지만", 사용자의 작업을 감시하고 메뉴 항목이 선택되면 서브루틴을 호출하는 것은 프레임워크이다. 메일 클라이언트 예에서 프레임워크는 키보드와 마우스 입력을 모두 추적하고, 사용자가 어떤 방식으로든 명령을 호출하면 해당 명령을 실행한다. 동시에 네트워크 인터페이스를 감시하여 새 메시지가 도착했는지 확인하고, 네트워크 활동이 감지되면 화면을 새로 고친다. 동일한 프레임워크를 스프레드시트 프로그램이나 텍스트 편집기의 골격으로 사용할 수 있다. 반대로, 프레임워크는 웹 브라우저, 스프레드시트 또는 텍스트 편집기에 대해 아무것도 모르며, 해당 기능을 구현하려면 사용자 지정 코드가 필요하다.

제어 반전은 재사용 가능한 코드와 문제별 코드가 애플리케이션에서 함께 작동하더라도 독립적으로 개발된다는 것을 강하게 암시한다. 콜백, 스케줄링, 이벤트 루프, 의존성 주입은 제어 반전 원칙을 따르는 디자인 패턴의 예이지만, 이 용어는 객체 지향 프로그래밍의 맥락에서 가장 일반적으로 사용된다.

제어 반전은 다음과 같은 설계 목적으로 사용된다.

  • 어떤 태스크의 실행을 구현으로부터 분리한다.
  • 어떤 모듈을, 목적하는 태스크에만 집중시킨다.
  • 모듈을 만들 때 다른 시스템이 무엇을 어떻게 하는지에 대해 가정하면서 코딩하는 것에서 벗어나 계약에 의존하여 코딩한다. (계약 프로그래밍)
  • 모듈을 대체할 때의 부작용을 예방한다.


전통적인 프로그래밍에서는 비즈니스 로직흐름 제어가 서로 정적 결합된 객체군에 의해 결정된다. 제어 반전을 사용하면 흐름 제어는 프로그램 실행 중에 구축된 객체 그래프에 의존하여 결정된다. 추상화를 매개로 객체 간의 상호 작용 관계를 정의함으로써 이러한 동적인 흐름 제어가 가능해진다. 이러한 실행 시 결합(지연 결합)은 의존성 주입 또는 서비스 로케이터 패턴과 같은 메커니즘으로 실현된다.

의존성 주입에서 의존하는 측의 객체 또는 모듈은 그 의존 대상 객체와 실행 시에 결합된다. 특정 어떤 객체가 프로그램 실행 중에 그 의존 관계를 충족하게 될지는 정적 코드 분석을 수행하는 컴파일 시에는 알 수 없다. 여기서는 객체 간의 상호 작용을 예로 설명했지만, 이 원칙은 객체 지향 프로그래밍 외의 다른 프로그래밍 기법에도 적용된다.

실행 중인 프로그램에서 객체끼리 서로 연결하려면 연결되는 객체끼리 호환 가능한 인터페이스를 가지고 있어야 한다. 예를 들어, 클래스 A는 그 동작을 인터페이스 I에 위임하고, I는 클래스 B에 의해 구현된다고 가정한다. 이와 같이 되어 있다면 프로그램은 AB를 인스턴스화한 후에 BA에 주입할 수 있다.

3. 2. 제어 반전에서의 흐름

제어 반전(IoC)에서는 프로그램의 흐름이 일반적인 프로그래밍 방식과 다르게 동작한다. 전통적인 프로그래밍에서는 비즈니스 로직이 서로 정적 결합된 객체들에 의해 결정되지만, IoC에서는 프로그램 실행 중에 만들어지는 객체 그래프에 따라 흐름이 결정된다.[14] 이러한 동적인 흐름은 추상화를 통해 정의된 객체 상호작용으로 가능해진다.

전통적인 텍스트 기반 인터페이스에서는 main 함수가 메뉴 라이브러리를 호출하여 사용자에게 선택지를 제공하고, 사용자의 선택에 따라 해당 명령을 실행한다.[5] 이메일 클라이언트를 예로 들면, "새 메일 읽기", "답장하기", "새 메일 작성" 등의 명령을 표시하고 사용자가 명령을 선택할 때까지 프로그램 실행이 멈춘다.

반면, IoC를 사용하면 프로그램은 소프트웨어 프레임워크를 기반으로 작성된다. 이 프레임워크는 윈도우 시스템, 메뉴, 마우스 제어와 같은 일반적인 동작 및 그래픽 요소를 담당한다. 개발자는 메뉴 항목을 제공하고 각 항목에 대한 코드를 등록하는 등 프레임워크의 "빈칸을 채우는" 방식으로 코드를 작성한다. 사용자의 입력을 감지하고 해당 코드를 호출하는 것은 프레임워크의 역할이다. 메일 클라이언트 예시에서 프레임워크는 키보드와 마우스 입력을 모두 추적하고, 네트워크를 통해 새 메시지가 도착했는지 확인하며, 필요에 따라 화면을 업데이트한다.

이러한 지연 바인딩은 의존성 주입이나 서비스 로케이터 패턴과 같은 메커니즘을 통해 이루어진다. IoC에서는 코드가 컴파일 시점에 정적으로 연결될 수도 있지만, 외부 구성을 통해 실행할 코드를 찾는 방식을 사용하기도 한다.

의존성 주입에서는 종속 객체 또는 모듈이 런타임에 필요한 객체와 연결된다. 어떤 객체가 의존성을 충족할지는 컴파일 타임의 정적 코드 분석으로는 알 수 없다. 이러한 원칙은 객체 지향 프로그래밍뿐만 아니라 다른 프로그래밍 방법론에도 적용될 수 있다.

프로그램 실행 중에 객체를 서로 연결하려면 호환되는 소프트웨어 인터페이스가 필요하다. 예를 들어, 클래스 `A`가 인터페이스 `I`에 동작을 위임하고, 클래스 `B`가 `I`를 구현하는 경우, 프로그램은 `A`와 `B`를 인스턴스화하고 `B`를 `A`에 주입한다.

소프트웨어 프레임워크, 콜백, 스케줄러, 이벤트 루프, 템플릿 메서드는 IoC 원칙을 따르는 디자인 패턴의 예시이며, IoC는 객체 지향 프로그래밍에서 주로 사용된다.[4] IoC는 "할리우드 원칙: 우리에게 전화하지 마세요. 저희가 전화드리겠습니다"라고도 불린다.[1]

3. 3. 결합도 감소 및 유연성 증가

제어 반전(IoC)을 통해 코드 간의 결합도를 낮추고, 유연성과 재사용성을 높일 수 있다.

기존의 프로그래밍 방식에서는 `ServerFacade` 클래스가 `DAO` 객체의 구체적인 구현 방식(예: `businessLayer` 객체가 `pRequest`를 검증하는 방법, `Aspect` 객체가 `DAO`에서 처리한 `pRequest`를 변환하는 방법)에 직접적으로 의존했다. 이로 인해 `ServerFacade` 클래스는 `DAO`와 강하게 결합되어, 코드의 유연성과 재사용성이 떨어진다.

```java

public class ServerFacade

{

public Object respondToRequest(Object pRequest)

{

if(businessLayer.validateRequest(pRequest))

{

DAO.getData(pRequest);

return Aspect.convertData(pRequest);

}

return null;

}

}

```

하지만 제어 반전 개념을 적용하면, `ServerFacade` 클래스는 `DAO` 객체의 구체적인 구현 방식에 의존하지 않고, `DAO` 인터페이스에만 의존하게 된다. `respondToRequest` 메서드는 `DAO` 객체를 인자로 받아 `getData` 메서드를 호출하며, 실제 어떤 `DAO` 구현체가 사용될지는 외부에서 결정된다.

```java

public class ServerFacade

{

public Object respondToRequest(Object pRequest, DAO dao)

{

return dao.getData(pRequest);

}

}

```

이처럼 제어 반전을 사용하면, 프로그램 실행 중에 구축된 객체 그래프에 따라 흐름이 결정되는 동적인 구조를 만들 수 있다. 이러한 지연 바인딩은 의존성 주입이나 서비스 로케이터 패턴과 같은 메커니즘을 통해 구현할 수 있다.[4]

전통적인 프로그래밍에서는 비즈니스 로직흐름 제어가 서로 정적 결합된 객체에 의해 결정되지만, 제어 반전을 사용하면 프로그램 실행 중에 구축된 객체 그래프에 의존하여 흐름 제어가 결정된다. 추상화를 통해 객체 간 상호 작용을 정의함으로써 이러한 동적 흐름 제어가 가능하며, 실행 시 결합(지연 결합)은 의존성 주입 또는 서비스 로케이터 패턴으로 구현된다.

의존성 주입에서, 의존하는 객체 또는 모듈은 실행 시간에 필요한 객체에 연결된다. 어떤 객체가 종속성을 충족할지는 컴파일 타임에 정적 코드 분석으로 알 수 없다. 이 원칙은 객체 지향 프로그래밍 외 다른 프로그래밍 방법론에도 적용 가능하다.

실행 중인 프로그램이 객체를 서로 바인딩하려면 객체는 호환되는 소프트웨어 인터페이스를 가져야 한다. 예를 들어, 클래스 `A`가 인터페이스 `I`에 동작을 위임하고 `I`가 클래스 `B`에 의해 구현되면, 프로그램은 `A`와 `B`를 인스턴스화한 다음 `B`를 `A`에 주입한다.

4. 구현 방법

제어 반전은 다양한 방법으로 구현될 수 있다. 전통적인 프로그래밍에서는 main 함수가 메뉴 라이브러리를 호출하여 사용자에게 명령 목록을 표시하고 선택을 받는 방식이었다. 예를 들어, 이메일 클라이언트는 새 메일 로드, 답장, 새 메일 작성 등의 명령을 표시하고 사용자가 키를 눌러 명령을 선택할 때까지 프로그램 실행이 차단된다.[5]

반면, 제어 반전을 사용하면 소프트웨어 프레임워크를 통해 일반적인 동작(예: 윈도우 시스템, 메뉴, 마우스 제어)을 처리하고, 사용자 지정 코드는 프레임워크에 메뉴 항목 등을 제공하는 방식으로 "빈칸을 채우는" 형태로 구현된다. 사용자의 작업을 감시하고 서브루틴을 호출하는 것은 프레임워크의 역할이다. 메일 클라이언트 예시에서 프레임워크는 키보드와 마우스 입력을 모두 추적하고, 사용자가 호출한 명령을 실행하며, 동시에 네트워크 인터페이스를 감시하여 새 메시지가 도착하면 화면을 갱신한다. 이러한 프레임워크는 스프레드시트나 텍스트 편집기 등 다른 프로그램의 골격으로도 사용될 수 있다.[5]

제어 반전은 재사용 가능한 코드와 문제별 코드가 함께 작동하면서도 독립적으로 개발될 수 있다는 것을 의미한다. 콜백, 스케줄러, 이벤트 루프 등은 제어 반전 원칙을 따르는 디자인 패턴의 예시이며, 객체 지향 프로그래밍에서 주로 사용된다.[4] 제어 반전은 "할리우드 원칙: 우리에게 전화하지 마세요. 저희가 전화드리겠습니다"라는 말로 표현되기도 한다.[1]

전통적인 프로그래밍에서는 흐름이 서로 정적 결합된 객체에 의해 비즈니스 로직이 결정되지만, 제어 반전을 사용하면 흐름은 프로그램 실행 중에 구축된 객체 그래프에 따라 달라진다. 이러한 동적 흐름은 추상화를 통해 정의된 객체 상호 작용에 의해 가능하며, 지연 바인딩은 의존성 주입, 서비스 로케이터와 같은 메커니즘을 통해 달성된다. 컴파일 시점에 코드가 정적으로 연결될 수도 있지만, 외부 구성을 통해 실행할 코드를 찾을 수도 있다.[20]

제어 반전의 구현 방식은 다음과 같다:



마틴 파울러는 처음 세 가지 방식을 논의했으며,[20] 문맥화된 참조는 일반적으로 서비스 로케이터를 사용하여 구현된다.[21]

"제어 반전"은 기술보다 어떤 목적으로 사용하는지가 중요하며, 위에 언급된 구현 방식에만 국한되지 않는다.

4. 1. 의존성 주입 (Dependency Injection)

의존성 주입은 제어 반전(IoC)을 구현하는 일반적인 방법 중 하나로, 객체 간의 의존 관계를 객체 내부가 아닌 외부에서 설정하여 주입하는 방식이다.

스프링 프레임워크와 같은 자바 프레임워크의 "IoC 컨테이너"에서는 의존성 주입 패턴(객체에 필요한 서비스를 전달하는 것)을 "제어 반전"이라는 용어로 구체적으로 지칭하기도 한다.[4] 이러한 의미에서 "제어 반전"은 프레임워크가 응용 프로그램 객체에서 사용되는 의존성 구현에 대한 제어를 부여하는 것을 의미한다.[11]

전통적인 프로그래밍에서는 비즈니스 로직흐름 제어가 서로 정적 결합된 객체군에 의해 결정되지만, 제어 반전을 사용하면 흐름 제어가 프로그램 실행 중에 구축된 객체 그래프에 의존하여 결정된다. 추상화를 통해 객체 간의 상호 작용 관계를 정의함으로써 이러한 동적인 실행 시 결합(지연 바인딩)을 의존성 주입 또는 서비스 로케이터 패턴과 같은 메커니즘으로 실현할 수 있다.

의존성 주입에서, 의존하는 측의 객체 또는 모듈은 실행 시에 의존 대상 객체와 결합된다. 어떤 객체가 프로그램 실행 중에 그 의존 관계를 충족할지는 정적 코드 분석을 수행하는 컴파일 시에는 알 수 없다.

실행 중인 프로그램에서 객체끼리 서로 연결하려면, 연결되는 객체끼리 호환 가능한 인터페이스를 가지고 있어야 한다. 예를 들어, 클래스 `A`가 인터페이스 `I`에 동작을 위임하고, `I`가 클래스 `B`에 의해 구현된다면, 프로그램은 `A`와 `B`를 인스턴스화한 후에 `B`를 `A`에 주입할 수 있다.

제어 반전을 구현하기 위한 몇 가지 기본 기술은 다음과 같다.

  • 팩토리 패턴 사용
  • 서비스 로케이터 패턴 사용
  • 의존성 주입 사용
  • 파라미터 주입
  • 템플릿 메서드 패턴 활용
  • 전략 패턴 활용
  • 문맥화된 참조(contextualized lookup)


마틴 파울러는 그의 논문에서 생성자 주입, 세터 주입, 인터페이스 주입 방식을 논의했다.[20] 문맥화된 참조는 일반적으로 서비스 로케이터를 사용하여 구현된다.[21]

"제어 반전"은 기술보다 어떤 목적으로 사용하는지가 중요하며, 이러한 기술에만 국한되지 않는다.

4. 1. 1. 생성자 주입

생성자를 통해 의존 객체를 주입하는 방식이다.[20][21]

4. 1. 2. 세터 주입

의존성 주입의 한 종류로, 세터(setter) 메서드를 이용하여 의존 객체를 주입받는 방식이다.[20]

4. 1. 3. 인터페이스 주입

인터페이스 주입은 의존성 주입의 한 형태로, 인터페이스를 통해 의존 객체를 주입하는 방식이다.[20]

4. 2. 서비스 로케이터 패턴 (Service Locator Pattern)

서비스 로케이터 패턴을 사용하여 필요한 객체를 찾아 사용하는 방식이다.[20][21]

4. 3. 팩토리 패턴 (Factory Pattern)

객체 지향 프로그래밍에서 제어 반전을 구현하는 기술 중 하나로 팩토리 패턴이 있다. 팩토리 패턴은 팩토리 클래스를 사용하여 객체 생성을 캡슐화하고, 객체 생성 로직을 외부로부터 숨기는 방식이다.[20]

4. 4. 템플릿 메서드 패턴 (Template Method Pattern)

소프트웨어 프레임워크를 사용하는 프로그램에서 일반적인 동작과 그래픽 요소는 프레임워크가 처리하고, 사용자 지정 코드는 "빈칸을 채우는" 방식으로 구현된다. 사용자의 작업을 모니터링하고 메뉴 항목이 선택되면 해당 서브루틴을 호출하는 것은 프레임워크의 역할이다. 이러한 방식은 상위 클래스에서 알고리즘의 골격을 정의하고 하위 클래스에서 구체적인 구현을 제공하는 템플릿 메서드 패턴과 관련이 있다.[5]

템플릿 메서드 패턴은 제어 반전 원칙을 따르는 디자인 패턴 중 하나이며, 객체 지향 프로그래밍에서 자주 사용된다.[4]

4. 5. 전략 패턴 (Strategy Pattern)

객체 지향 프로그래밍에서 제어 반전을 구현하기 위한 여러 기술 중 하나로 전략 패턴이 있다. 전략 패턴은 알고리즘 군을 정의하고, 각 알고리즘을 캡슐화하여 상호 교환 가능하게 만드는 방식이다.[20]

5. 제어 반전의 활용 사례

메사 프로그래밍 환경, XDE(1985)[1], 비주얼 베이직 (클래식)(1991) 등에서 제어 반전이 사용되었다. HTML DOM 이벤트, 스프링 프레임워크[11], ASP.NET Core[12], 템플릿 메서드 패턴 등도 제어 반전의 활용 사례이다.

5. 1. 스프링 프레임워크 (Spring Framework)

스프링 프레임워크는 자바 기반의 엔터프라이즈 애플리케이션 개발을 위한 프레임워크로, 제어 반전과 의존성 주입을 핵심 기능으로 제공한다.[11]

5. 2. ASP.NET Core

ASP.NET Core는 마이크로소프트에서 개발한 크로스 플랫폼 웹 애플리케이션 프레임워크로, 의존성 주입을 기본적으로 지원한다.[12]

다음은 ASP.NET Core 웹 애플리케이션 예제 코드이다. 이 코드는 웹 애플리케이션 호스트를 생성하고 엔드포인트를 등록한 다음 제어 권한을 프레임워크에 넘긴다.[12]



var builder = WebApplication.CreateBuilder(args);

var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();


5. 3. DOM 이벤트

웹 브라우저의 DOM 이벤트 처리 방식은 제어 반전의 한 예시로 볼 수 있다. 애플리케이션 개발자는 `document.addEventListener()`를 사용하여 콜백을 등록한다.

```html









DOM 레벨 2





DOM 레벨 2 이벤트 핸들러










6. 비판 및 고려 사항

제어 반전은 코드 복잡성을 증가시키고 런타임 오류 발생 가능성을 높일 수 있다.[22][19]

6. 1. 복잡성 증가

제어 반전은 다른 추상화 기법과 마찬가지로 장점과 단점을 모두 가지고 있다. 특정 작업은 단순화되지만, 애플리케이션의 협조 동작은 더 복잡해진다. 데이비드 휠러는 "컴퓨터 과학의 모든 문제는 또 다른 수준의 간접성을 통해 해결할 수 있다"라는 유명한 격언을 남겼다.[22] 이 말에서 "간접성"을 "추상화(abstraction)"로 잘못 인용하는 경우가 많다. Kevlin Henney는 이 격언에 대해 "…단, 레이어가 너무 많아서 발생하는 문제를 제외하고"라는 말을 덧붙였다.

같은 이야기가 제어 반전에도 적용된다. Robert C. Martin의 기사[19]에 있는 코드를 예로 들면, 최종 코드에는 5개의 클래스가 정의되어 있지만, 절차적 프로그래밍에서는 하나의 메서드(루틴)로 구현할 수 있다. 제어 반전은 두 개의 구현을 서로 분리한다는 장점이 있지만, 동시에 전체적으로 협조 동작을 시킬 때 복잡성이 증가한다.

6. 2. 런타임 오류 가능성

데이비드 휠러는 "컴퓨터 과학의 모든 문제는 또 다른 수준의 간접성을 통해 해결할 수 있다"라는 유명한 격언을 남겼다.[22] Kevlin Henney는 이 격언에 대해 "…단, 레이어가 너무 많아서 발생하는 문제를 제외하고"라는 말을 덧붙였다.

이러한 격언은 "제어 반전"에도 적용된다. Robert C. Martin의 기사[19]에 제시된 코드를 예로 들면, 최종 코드에는 5개의 클래스가 정의되어 있지만, 절차적 프로그래밍에서는 하나의 메서드(루틴)로 구현할 수 있다. "제어 반전"은 두 구현을 분리한다는 장점이 있지만, 동시에 전체적인 협조 동작을 복잡하게 만든다.

참조

[1] 학술지 The Mesa Programming Environment https://dl.acm.org/d[...] 1985-06-25
[2] 문서 Visual_Basic_(classic)
[3] 학술지 Designing Reusable Classes http://www.laputan.o[...] 2014-04-29
[4] 웹사이트 Inversion of Control Containers and the Dependency Injection pattern https://martinfowler[...] 2023-06-04
[5] 문서 Dependency Injection http://martinfowler.[...]
[6] 블로그 Inversion of Control http://martinfowler.[...]
[7] 웹사이트 Introduction to Jackson Design Method http://www.jacksonwo[...]
[8] 웹사이트 Object-Oriented Frameworks, A survey of methodological issues https://www.research[...] Department of Computer Science, Lund University 1996-02
[9] 웹사이트 On Inversion of Control http://www.betaversi[...] 2004-01-22
[10] 웹사이트 IOC Patterns - Avalon Framework https://svn.apache.o[...] 2023-06-08
[11] 웹사이트 Spring Framework The IoC container https://docs.spring.[...] 2023-05-25
[12] 웹사이트 "Routing in ASP.Net Core" https://learn.micros[...] microsoft 2023-05-25
[13] 웹사이트 Designing Reusable Classes http://www.laputan.o[...] Department of Computer Science University of Illinois at Urbana-Champaign 2014-04-29
[14] 문서 Dependency Injection http://martinfowler.[...]
[15] 서적 Head First デザインパターン オライリー・ジャパン
[16] 블로그 Inversion of Control on Martin Fowler's Bliki http://martinfowler.[...]
[17] 웹사이트 Design pattern – Inversion of control and Dependency injection http://www.codeproje[...]
[18] 웹사이트 Design Better Software with the Inversion of Control Pattern http://www.devx.com/[...]
[19] 웹사이트 The Dependency Inversion principle http://www.objectmen[...]
[20] 웹사이트 Inversion of Control Containers and the Dependency Injection Pattern http://www.martinfow[...]
[21] 웹사이트 IoC Types http://docs.codehaus[...]
[22] 서적 Structured Computer Organization Prentice-Hall



본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.

문의하기 : help@durumis.com