객체 지향 프로그래밍은 프로그래밍 언어를 설계하는 새로운 방식일 뿐만 아니라 프로그램을 설계하는 완전히 다른 방식이기도 합니다.
이 논문은 스몰토크(Smalltalk)로 시스템을 설계하는 것이 어떤 것인지 설명합니다. 특히, 객체 지향 프로그래밍의 주요 동기 중 하나가 소프트웨어 재사용이기 때문에,
이 논문은 클래스가 어떻게 개발되어야 재사용 가능하게 되는지를 설명합니다.
IoC란 무엇인가?
제어 반전, 프로그래머가 작성한 프로그램이 재사용 라이브러리의 흐름 제어를 받게되는 소프트 웨어 디자인 패턴을 말한다.
Inversion of Control 이라고 부르는데, 전통적인 프로그래밍에서 흐름은 프로그래머가 작성한 프로그램이 외부 라이브러리의 코드를 호출해 이용한다.
하지만 제어 반적이 적용된 구조에서는 외부 라이브러리의 코드가 프로그래머가 작성한 코드를 호출한다.
IoC의 시작은
1988년 OOP의 기념비적인 논문 중 하나인 Ralph E.Johnson 과 Brain Foote가 작성한 "Designing Reusable Classes" (1988, Ralph Johnson & Brian Foote) 에서 처음 설명된다.
이때 재사용성을 늘리기 위해 많은 노력을 한다.
이들은 이 논문에서 OOP의 원칙을
다형성 Polymorphism : 다양한 객체들이 동일한 메세지를 통해 상호작용할 수 있는 특성
프로토콜 Protocol : 객체들이 제공해야할 서비스나 메서드 집합, 즉 인터페이스를 명확히 정의하는 것을 의미
상속 Inheritance : 기존 클래스의 특성과 행동을 새로운 클래스가 물려받아 확장하거나 수정할 수 있게 해주는 매커니즘
추상화 클래스 Abstract Classes : 구체적인 구현은 제공하지 않고, 서브 클래스가 반드시 구현해야하는 인터페이스나 기본 구조를 정의하는 클래스
이라고 정의한다.
(일반적으로 지금 쓰는 OOP와 꽤 다르기때문에 지금 이렇게 말하면 안된다)
(우리가 지금 쓰는 모습과 형태가 다른 것을 알 수 있다. 이는 OOP가 앨런 케이의 개념에서 후에 우리가 쓰게될 Booch의 개념까지의 이동을 보여주는 좋은 자료다)
여기에서 FrameWorks를 정의하는데
FrameWorks=Component + Inversion of Control
라는 개념을 정리하면서 IoC를 설명한다.여기서 IoC는 프레임워크가 애플리케이션의 흐름을 제어하는 방식으로 개념을 설명한다.
현대적 프레임워크의 개념을 정립한 논문 중 하나이자 IoC를 체계적으로 정립한 최초의 논문이라고 이야기되는 이 논문에서
IoC는 기존의 프로그램이 사용자가 직접 흐름을 제어하는 것과 달리, 외부에서 흐름을 제어하고 사용자는 필요한 부분을 구현하는 방식을 의미한다.
(논문에서는 그것을 외부를 프레임워크라고 지칭하지만)
(다만 IoC 용어의 첫 시작이 대부분은 Designing Reusable Classes(1988) 에서 시작이라고 하지만 그전까지 이러한 개념이 있다라고 알음알음 쓰다가
용어를 확정적으로 정한 논문이라고 보기도 한다)
쉽게 예시를 들어보자
전통적인 프로그래밍 방식에서는 객체가 필요한 시점에서 스스로를 생성하거나, 다른 객체를 생성하여 사용한다.
즉 프로그램의 흐름은 객체(Object) 자신이 주도하게 된다.
반면 IoC를 적용하면 객체는 자신이 사용할 객체를 직접 생성하거나 찾지 않는다.
대신 외부 컨테이너가 필요한 객체를 생성하고, 객체간의 의존관계를 설정하여 제공한다.
이를 통해 객체는 자신의 핵심로직에만 집중 할 수 있게된다
예시는 IoC중 가장 기초중 하나인 생성자 주입이다.
사실 이렇게 예시만 덩그러니 두면 사실 이해가 어려울 것이다.
그러니까 IoC의 핵심 개념을 소개한다.
Don't Call, We'll Call You - Sugarloaf 1974
IoC의 일반적 핵심 개념을 요약하면 다음과 같다.
The Mesa Programming Environment -Richard E. Sweet 1983
할리우드 원칙(HollyWood principle): 1983년 메사 프로그래밍 환경에 대해서 설명한 논문에서 최초로 등장한 후, 현대적 OOP의 아버지인 4인방 중 한명인 존 블라시디스(John Vlissides)가 C++ 리포트에 쓰고, 마틴파울러가 인용해서 유명해진 원칙이다.
이 원칙은 할리우드 영화 제작사가 오디션 배우에게 전화하지말고, 연락처 주시면 우리가 전화드릴게요에서 유래된 개념이다.
쉽게 요약하면 다음과 같다.
1. 배우(호출자)가 감독(프레임워크)에게 능동적으로 연락해서 출연기회를 구걸하는 것이 아니라, 감독이 필요한 경우 필요한 배우를 직접 선택해서 '캐스팅 전화(Call Back)' 한다는 것으로. 제어 권한이 배우가 아닌 감독에게 있다는 점을 강조한 비유이다.
어쨌건 IoC는 제어의 역전을 뜻하고, 프로그램의 흐름 제어가 개발자에게서 프레임워크로 넘어가는 것을 의미하는데, 개발자는 프레임워크가 제공하는 규칙과 API를 따라 코드를 작성하고, 프레임 워크는 객체의 생명 주기와 상호작용을 관리한다.
IoC 구현 패턴을 크게 자주보이는 것을 기준으로 보면 2가지로 볼 수 있는데
아래의 패턴들은 코드 레벨 또는 객체간의 상호작용을 통해 '흐름 제어'를 역전시키는 IoC 패턴이다
콜백(Callback)
-이벤트 핸들링, GUI 프레임워크등에서 많이 볼 수 있는 그것
템플릿 메서드 패턴(Template Method Pattern)
-상위 클래스에서 전체 알고리즘 흐름(템플릿)을 정의하고, 하위 클래스가 일부 단계를 오버 라이드(Override)하는 패턴
Publisher-Subscriber 패턴
-주제Subect가 특정 이벤틀 발생시켰을때, 등록된 Publisher에게 알림을 보내는 방식
(Spring의 IoC 컨테이너 모식도)
아래의 패턴은 객체 생성과 의존성 연결(주입)을 프레임워크나 컨테이너에게 위임해, 사용자는 “필요한 의존 관계”만 정의하면 자동으로 주입받게 하는 방식이다
IoC 컨테이너(IoC Container)
IoC를 실제로 구현하고 관리하는 역할을 하는 것이 IoC 컨테이너인데, IoC 컨테이너는 다음과 같은 역할을 한다.
1.객체의 생성 및 관리: 애플리케이션에서 필요한 객체들을 생성하고 그 생명 주기를 관리. (객체의 생성, 초기화, 소멸 등)
2.의존성 주입(Dependency Injection, DI): 객체 간의 의존 관계를 분석하고, 필요한 객체를 다른 객체에게 주입한다.
이를 통해 객체들은 서로 결합도를 낮추고 독립적으로 동작할 수 있다
3.객체의 검색 및 제공: 필요에 따라 컨테이너에 등록된 객체를 검색하여 제공
이러한 IoC의 장점은
-결합도 감소: 객체간의 의존성을 줄이고, 의존성을 줄이고, 코드 재사용성을 높임
-유연성 향상: 설정파일이나 다른 매커니즘을 통해 의존성을 쉽게 변경할 수 있음
-코드 단순화:객체 생성 및 의존성 관리 코드가 줄어들어 코드가 간결해진다.
근데 갑자기 이 글을 읽는 독자들은 갑자기 IoC 이야기하다가 의존성 주입(DI)이 라는 단어가 나와서 놀랐을 것이다.
이제 DI가 무엇인지 설명하겠다.
우선 IoC라는 것은 너무 설명이 넓고 많은 범위를 이야기하여 이해를 어렵게 하지 않는가?
그래서 우리 선배 프로그래머이자 위대한 성현 마틴 파울러는 여러사람들간의 논의 끝에 하나의 글을 작성하게 된다.
그것이 바로 프로그래밍 역사에 길이 남을 명문인
Inversion of Control Containers and the Dependency Injection pattern(2004)이다.
이 에세이에서 IoC의 다양한 형태를 정리하고, 그중에서 IoC의 한 패턴으로써 Dependency Injection(DI) 라는 개념을 정의한다.
제어의 역전이라는 용어는 너무 일반적이어서 사람들이 혼란스러워합니다.
그렇기때문에 다양한 IoC 옹호자들과 많은 논의를 거쳐 의존성 주입이라는 이름을 사용하기로 결정했습니다.
그리고 여기서 DI형태 중 특별한 형태 3가지를 예시로 들어준다.
생성자 주입(Constructor Injection): 객체 생성시 생성자를 통해 의존성 주입 -(Spring,DI 컨테이너에서 많이 사용)
세터 주입(Setter Injection): 세터 메서드를 통해 의존성을 주입 (다양한 구성 가능, 주로 XML 과 사용)
인터 페이스 주입(Interface Injection): 인터페이스를 통해 의존성을 주입한다. (필자가 자주 사용)
| 주입 방식 | 장점 | 단점 | 사용예시 | |
| 생성자 주입(Constructor Injection) | 불변성(Immutable) 보장, 객체가 완전히 초기화됨 | 순환 의존성이 발생할 경우 처리 어려움 | 필수 의존성이 있는 경우 사용 | |
| 세터 주입(Setter Injection) | 선택적 의존성 주입 가능, 순환 의존성 해결 쉬움 | 불변성 보장 어려움, 객체 상태가 변경될 가능성 있음 | 의존성이 필수가 아닌 경우 사용 | |
| 인터페이스 주입(Interface Injection) | 특정 객체만 주입 가능하도록 제한할 수 있음 | 유지보수 어려움, 코드가 복잡해질 수 있음 |
|
최종적으로 이제 이 글을 단 2줄로 요약하자
IoC (제어의 역전): 제어 흐름을 외부에 위임하는 상위 개념. 프레임워크, 콜백, 이벤트 등 다양한 방식으로 구현 가능.
DI (의존성 주입): IoC를 구현하는 하위 개념. 객체 간의 의존성을 외부에서 주입하는 특정 패턴.
마지막으로, IoC와 DI는 단순히 기술적 도구가 아닌, 소프트웨어 설계의 철학을 반영한 개념이다.
이를 통해 객체 간의 결합도를 낮추고, 코드의 유연성과 테스트 용이성을 높일 수 있다
이러한 원칙을 이해하고 적용한다면, 더 나은 소프트웨어를 설계하고 개발하는 데 큰 도움이 될 것이다.
개추 ㅋ
여윽시 프갤 최고조넘게이
템플릿 메서드가 근데 지금 시대에 필요함? 고차함수랑 프록시로 전부 대체 가능하지 않나
게임에서는 아직도 씀. 그리고 분리때문에 보기 편하기때문에 역시 프로그래머 선택인거지. FP비슷하게 쓸꺼면 걍 고차함수 쓰고, 공통로직이 복잡할수록 템플릿 메서드 쓰는 경우가 낫다고 앎
개추
모르는입장에서 봐야 글이 좋은지 알겠는데 아는입장이라 감히 평가하기 어렵네 재밌게 읽음 개추
https://m.dcinside.com/board/programming/2818126 댓글좀
고마워
넘좋은글이네