CS

DI & DIP 의존성주입과 의존관계 역전원칙

kark 2024. 12. 11. 00:04
728x90

의존성 주입이란 메인 모듈이 직접 다른 하위 모듈을 참조하지 않고 중간 매개체를 통해

모듈 간 간접적인 의존성을 주입하는 방식이다.

 

 

이미지 출처 https://velog.io/@tiger/CS-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4-%EC%9D%98%EC%A1%B4%EC%84%B1-%EC%A3%BC%EC%9E%85

 

의존성 주입 전 이미지의 경우 메인 모듈이 하위 모듈을 직접 참조하고 있으며

의존성 주입 후 이미지의 경우 메인 모듈이 모든 하위 모듈을 직접 참조하지 않고 중간 주입자를 통해

상호작용을 진행하는 구조이다.

 

의존한다 의 의미

A 가 B 에 의존한다 => B 가 변하면 A 에 영향을 끼친다

public class A
{
    private B _b;

    public void Move()
    {
        _b.Move();
    }
}

public class B
{
    public void Move() // Move 메서드명 수정시 A 또한 수정과정이 필요함
    {

    }
}

 

위 코드에서 B 가 변경사항이 발생된다면 A 또한 영향이 있을 수 밖에 없다.

 

이러한 방식대로 그대로 코드를 작성할 경우

public class A
{
    public void Do()
    {
        Debug.Log("A가 뭔가 한다!");
    }
}

public class B
{
    public void Do()
    {
        Debug.Log("B가 뭔가 한다!");
    }
}

public class Project
{
    public A _myA;
    public B _myB;

    public Project(A a, B b)
    {
        this._myA = a;
        this._myB = b;
    }

    public void Action()
    {
        _myA.Do();
        _myB.Do();
    }
}

 

프로젝트는는 직접 A와 B를 참조하여 뭔가의 로직을 진행시키게 된다.

이러한 경우 결합도가 높으므로 A 나 B 둘중에서 변경이 발생된다면 프로젝트 클래스 또한 변경이 필요할 수 있다.

 

이러한 관계를 중간 인터페이스를 통해 관계를 역전시킬 수 있게된다.

 

public interface IDoable
{
    public void Do();
}

public class A : IDoable
{
    public void Do()
    {
        Debug.Log("A가 뭔가 한다!");
    }
}

public class B : IDoable
{
    public void Do()
    {
        Debug.Log("B가 뭔가 한다!");
    }
}

public class Project
{
    private List<IDoable> _doables = new List<IDoable>();

    public void AddDo(IDoable doable)
    {
        _doables.Add(doable);
    }

    public void Action()
    {
        foreach (var myDo in _doables)
        {
            myDo.Do();
        }
    }
}

public static class Container
{
    public static void Main()
    {
        Project project = new Project();
        project.AddDo(new A());
        project.AddDo(new B());

        project.Action();
    }
}

 

각 구체 클래스는 인터페이스의 메서드를 구현하기 위해 기본적인 제공 함수의 틀을 제공하며,

프로젝트 클래스의 경우 이 인터페이스의 기능만 활용하면 되므로

구체클래스가 변경되더라도 프로젝트의 코드는 변경되지 않는다.

'CS' 카테고리의 다른 글

실행 플랫폼 별 생성되는 기계어 코드가 다른 이유  (0) 2025.02.10
컴파일러 Compiler  (0) 2025.02.10
String 문자열의 불변성  (1) 2024.09.02
2의 보수  (0) 2024.07.14
컴퓨터의 사칙연산 (보수법의 필요성)  (0) 2024.07.14