IoC 컨테이너, DI 컨테이너?

이준호·2022년 9월 30일
0

스프링

목록 보기
1/1
post-thumbnail

서론

좋은 객체 지향 설계의 5가지 원칙 중 OCP와 DIP의 정의를 보면 개념적으로는 무엇을 말하고 싶은지 알지만 실제 코드 레벨에서 볼 때는 어떻게 이를 적용시킬지 난감했다.

DIP - 프로그래머는 '추상화에 의존해야지, 구체화에 의존하면 안된다'
OCP - 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다

DIP, OCP를 지키지 못하는 코드

interface Animal {
    void eat();
    void sleep();
}

class Lion implements Animal {
    @Override
    public void eat() {
        System.out.println("사자가 먹이를 먹음");
    }

    @Override
    public void sleep() {
        System.out.println("사자가 잠을 잠");
    }
}

class Tiger implements Animal {
    @Override
    public void eat() {
        System.out.println("호랑이가 먹이를 먹음");
    }

    @Override
    public void sleep() {
        System.out.println("호랑이가 잠을 잠");
    }
}

class Zookeeper {
    Animal animal1 = new Lion();
    Animal animal2 = new Tiger();

    void feeding() {
        animal1.eat();
        animal2.eat();
    }

    void night() {
        animal1.sleep();
        animal2.sleep();
    }
}

위 코드는 다형성을 이용해서 추상화를 잘 해낸 것 같지만 new Lion() new Tiger()와 같이 구체화에 의존하고 있다.

이렇게 DIP, OCP 원칙이 깨지는 것을 막고 진정한 추상화에만 의존하는 코드를 만들기 위해서는 관심사의 분리가 필요하다.

관심사의 분리로 DIP, OCP를 지키는 코드

class Zoo {
    public Animal makeLion() {
        return new Lion();
    }

    public Animal makeTiger() {
        return new Tiger();
    }

    public Zookeeper assignAnimal() {
        return new Zookeeper(makeLion(), makeTiger());
    }
}

class Zookeeper {
    Animal animal1;
    Animal animal2;

    public Zookeeper(Animal animal1, Animal animal2) {
        this.animal1 = animal1;
        this.animal2 = animal2;
    }

    void feeding() {
        animal1.eat();
        animal2.eat();
    }

    void night() {
        animal1.sleep();
        animal2.sleep();
    }
}

Zoo 클래스가 구현 객체를 생성하고, 역결하는 책임을 가지게 만들면서 Zookeeper 클래스는 실행에만 집중할 수 있게 된 것이다.
Zookeeper 클래스 내에는 구현체가 하나도 없이 추상화에만 의존하고 있지만 실제로 동작은 되는 것을 볼 수 있다. (Zoo에서 구현체를 주입 해주었기 때문)

IoC, DI, 그리고 컨테이너

IoC

제어의 역전(Inversion of Control)이란 프로그램의 제어 흐름을 직접 제어(Zookeeper)하는 것이 아니라 외부(Zoo)에서 관리하는 것을 제어의 역전이라 한다.

DI

외부에서 실제 구현 객체를 주입시켜는 것을 말한다.

new Zookeeper(makeLion(), makeTiger());

IoC컨테이너, DI컨테이너

Zoo처럼 객체를 생성하고 관리하면서 의존관계를 연결해주는 것을 IoC컨테이너 또는 DI컨테이너라 한다. (최근에는 주로 DI컨테이너라 한다)

profile
코딩 조아

0개의 댓글