강한 결합을 약한 결합으로(DI)

김영민·2022년 1월 30일
1

1. 강한 결합

  • 어떤 객체를 다른 클래스에서 생성하여 사용하였을 때, 해당 객체에 변경을 가하면 해당 객체를 생성한 다른 클래스에서도 똑같이 변경을 해줘야 하는 상태를 의미한다.
    다음 예시를 통해 더 자세히 알아보자.

1. Animal이라는 객체를 선언

public class Animal {
}

2. Cat이라는 클래스에서 Animal 객체를 생성

public class Cat{
    public Animal animal;
    
    public Cat() {
        this.animal = new Animal();
    }
}

3. Animal 클래스에서 Animal 객체에게 이름을 지어준다면,

public class Animal {
    public Animal(String name) {
    }
}

4. Cat 클래스에 있는 Animal 객체에게도 해당 변경사항을 적용시켜 줘야한다.

public class Cat{
    public Animal animal;
    
    public Cat() {
        this.animal = new Animal(String name);
    }
}
  • 문제점 : 만약 Animal 객체를 Dog, Chicken, Cow 같은 다른 클래스에서도 생성했었다면,
    변경사항을 수정하는데 더 긴 시간이 걸렸을 것이다. 이는 유지보수 측면에서 정말 최악일 수 있다.

  • 해결책 : 모든 클래스에서 객체를 생성하고 있기 때문에 이와 같은 문제가 발생하고 있다.
    그럼 객체를 한 번만 생성하고, 해당 객체를 재사용 한다면 이 문제는 해결될 수 있다.

2. 약한 결합

  • 위와 같은 해결책을 사용하는 것을 약한 결합이라고 한다. 약한 결합은 강한 결합과 반대로 객체를 변경해도 다른 곳에 아무런 영향이 주지 않는다.
    다음 예시를 통해 더 자세히 알아보자.

1. Animal 객체를 생성 (Animal 객체를 한 번만 생성)

public class Animal {
}

Animal animal = new Animal();

2. Cat 클래스 선언 및 객체 생성 (Animal 객체를 재사용)

public class Cat {
    private final Animal animal;
    
    public Cat(Animal animal) {
        this.animal = animal;
    }
}

Cat cat = new Cat(animal);

3. Animal 객체에게 이름을 지어줘도,

public class Animal {
}

Animal animal = new Animal(String name);

4. 변경을 할 데가 없다.

public class Cat {
    private final Animal animal;
    
    public Cat(Animal animal) {
        this.animal = animal;
    }
}
Cat cat = new Cat(animal);
  • 이처럼 생성된 객체를 재사용하면 변경사항을 한 번만 적용하면 되기 때문에 유지보수에도 상당히 유리한 것을 알 수 있다.

3. 의존성 주입(DI)을 통한 제어의 역전(IoC)

위에서 코드로 표현한 것을 이번엔 그림으로 나타내 보자.

  • 강한 결합

    강한 결합에서는 Animal 객체를 변경하면 Cat 클래스 내에 있는 Animal 객체도 똑같이 변경해줘야 하기 때문에 Animal 클래스에 의해 Cat클래스가 제어되고 있음을 볼 수 있다.

  • 약한 결합

    하지만 약한 결합에서는 객체를 따로 생성하기 때문에 객체를 필요시에만 가져다 쓸 수 있다. 이렇게 객체가 상황에 맞게 쓰여지는 것을 의존성 주입(Dependency Injection)이라고 한다.
    그리고 DI가 발생하면서 객체를 변경하면 해당 객체를 재사용한 곳에 자동적으로 반영이 되기 때문에 제어흐름이 뒤바뀌는 것을 알 수 있다. 이렇게 제어흐름이 바뀌는 것을 제어의 역전(Inversion of Control)이라고 한다.

4. 빈(Bean)으로 객체 생성 및 관리하기

  • DI를 위해서는 객체생성을 해야하는데 Spring Framework(Bean, Spring IoC)에서 그 역할을 대신 해준다.
    Bean은 스프링이 관리하는 객체를 의미하고,
    Spring IoC는 그런 Bean을 모아둔 통이라고 생각하면 된다.
profile
Macro Developer

0개의 댓글