순서
I. Dependency Injection(의존성 주입)
I-1. Dependency(의존성) 란?
I-2. Inversion Of Control (IOC)
II. Interface
III. 구현
I. Dependency Injection(의존성 주입)
결론
- 직접 객체들을 호출 하는 것이 아닌
제 3자인 중앙 매개체(Interface)를 거쳐 객체를 호출 하는 것이다.
-> 매개체로부터 "주입" 받는다.
- 컴파일시 객체 결정 -> 동적으로 결정
1. Dependency(의존성) 란?
개발할때 한 클래스에서 다른 클래스의 메소드를 사용하고 싶을 때
해당 클래스의 객체를 생성하게 된다.
: 생성하는 순간 의존성이 생긴다.
의존성의 존재는 필수 불가결하다.
하지만 이 의존성을 최소한으로 줄이고 싶다.
의존성이 강하다면 뭐 하나 바꾸려하면
사용하는 모든 클래스에서 선언, 구현 모든 것들을 일일이 변경해야하기 때문이다.
(강한 결합 : 확장성 떨어짐, 유지보수 취약)
그저 나는 내 부분의 개발만 신경쓰며 유연하게 하고 싶은 것이다.
<문제점>
public class CMyAnimal {
private Dog _dog;
public CMyAnimal() {
_dog = new Dog();
}
}
생성자 내부에서 딱 Dog를 지정해 컴파일 단계에 결정해버렸다.
-> 강한 의존성
ex) Dog 가 짖는 것 만약 고양이를 넣으려면 고양이가 우는 것,
뭐 할때마다 각 객체당 모든 작업을 넣어줘야함.
2. Inversion Of Control (IOC)
위에서 클래스 내부에서 객체를 직접 생성했다.
이 방식을 바꿔보려고 한다.
즉, 생성자의 인자로 어떤 객체를 생성할지 정하는 것이다.
Callee내부에서 생성 -> Caller가 지정해줌.
객체의 제어 권한이 외부로 역전된 것이다.
= Inversion Of Control (IOC)
public class CMyAnimal {
private Dog _dog;
// 방법1. 생성자 : Constructor Injection
public CMyAnimal(CDog dog) {
_dog = dog;
}
// 방법2. 함수 : Method Injection
public setDog(CDog dog) {
_dog = dog;
}
}
즉, 종속성 문제를 해결하기 위해 Ioc를 구현하고 싶은데,
다양한 방법 중 한가지가 DI 디자인 패턴인 것이다.
II. Interface
Interface의 필요성
: 동일한 성질의 그룹화
: 동일한 동작의 강제성
: 느슨한 결합
다양한 클래스 객체를 그룹화 하고 싶고,
하지만 비슷한 동작을 해야하고,
각 객체 자기 자신만 신경쓰고 싶은 것이다.
객체들의 관리를 하는 또 다른 객체가 필요하다.
-> 제 3자의 등장 = Interface 객체
각자 자신의 것만 개발해서 Interface에 등록하고
필요할때 인터페이스를 통째로 넘겨받고 선택하여 객체를 생성한다.
-> 인터페이스를 통해 객체를 주입받는다.
이 경우 내 객체, 네 객체의 관리 권한이 3자로 넘어갔다.
+) 이렇게 객체들을 관리하는 인터페이스를 Ioc Container라고 한다.
III. 구현
1. 간단한 구현
각 동물들은 IAnimal을 상속받고 IAnimal을 Container로 사용해보자.
public interface IAnimal {
// 인터페이스 내 함수는 무조건 abstract
void getSound();
}
public class CDog : IAnimal {
public void getSound() => Console.WriteLine("Dog Sound");
}
public class CCat : IAnimal {
public void getSound() => Console.WriteLine("Cat Sound");
}
// Callee
public class CMyAnimal {
private IAnimal _IAnimal;
public CMyAnimal(IAnimal Animal) {
_IAnimal = Animal;
}
public class CMain() {
public void Main() {
CMyAnimal myAnimal = new CMyAnimal(new CDog());
myAnimal.getSound();
}
}
Main에서 CMyAnimal을 생성하며 IAnimal 인터페이스를 생성하여 넘겨줬다.
- 인터페이스에 속한(상속받은) 객체를 인자로 넘겨주었다.
- 받은 Callee 부분에서는 이를 Interface 객체로 받게된다.
-> 들어올때마다 Dog니 Cat이니 형을 맞춰주어 객체를 생성할 필요가 없음.
2. C# System 방식
C#에서 DI 패턴은 다음과 같은 구조를 갖게된다.
1. 내가 사용할 클래스 및 인터페이스를 다른 곳에 주입하기 위해서 Register를 통해 등록
2. 주입받을 곳에서 Provide로 Interface객체로 주입받음.
C#은 다음과 같이 제공되는 System Framework를 통해 DI를 구현할 수 있다.
'Programming > 기타' 카테고리의 다른 글
[Programming][Architecture] C# 비 동기 프로그래밍(async, await, Task) (0) | 2023.02.13 |
---|---|
[Programming][Architecture] Asynchronous Messaging Pattern (0) | 2023.02.11 |
[Programming][C++] eigen 사용법 (선형대수 라이브러리) (0) | 2022.11.20 |
[Programming][C++] std::string<-> QString<-> char * 변환법(int 포함) (2) | 2021.01.04 |