강한 결합
- 어떤 객체를 다른 클래스에서 생성하여 사용하였을 때, 해당 객체에 변경을 가하면 해당 객체를 생성한 다른 클래스에서도 똑같이 변경을 해줘야 하는 상태를 의미한다.
다음 예시를 통해 더 자세히 알아보자.
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 같은 다른 클래스에서도 생성했었다면,
변경사항을 수정하는데 더 긴 시간이 걸렸을 것이다. 이는 유지보수 측면에서 정말 최악일 수 있다. - 해결책 : 모든 클래스에서 객체를 생성하고 있기 때문에 이와 같은 문제가 발생하고 있다.
그럼 객체를 한 번만 생성하고, 해당 객체를 재사용 한다면 이 문제는 해결될 수 있다.
약한 결합
- 위와 같은 해결책을 사용하는 것을 약한 결합이라고 한다. 약한 결합은 강한 결합과 반대로 객체를 변경해도 다른 곳에 아무런 영향이 주지 않는다.
다음 예시를 통해 더 자세히 알아보자.
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);
- 이처럼 생성된 객체를 재사용하면 변경사항을 한 번만 적용하면 되기 때문에 유지보수에도 상당히 유리한 것을 알 수 있다.
의존성 주입(DI)을 통한 제어의 역전(IoC)
위에서 코드로 표현한 것을 이번엔 그림으로 나타내 보자.
- 강한 결합
강한 결합에서는 Animal 객체를 변경하면 Cat 클래스 내에 있는 Animal 객체도 똑같이 변경해줘야 하기 때문에 Animal 클래스에 의해 Cat클래스가 제어되고 있음을 볼 수 있다. - 약한 결합
하지만 약한 결합에서는 객체를 따로 생성하기 때문에 객체를 필요시에만 가져다 쓸 수 있다. 이렇게 객체가 상황에 맞게 쓰여지는 것을 의존성 주입(Dependency Injection)이라고 한다.
그리고 DI가 발생하면서 객체를 변경하면 해당 객체를 재사용한 곳에 자동적으로 반영이 되기 때문에 제어흐름이 뒤바뀌는 것을 알 수 있다. 이렇게 제어흐름이 바뀌는 것을 제어의 역전(Inversion of Control)이라고 한다.
빈(Bean)으로 객체 생성 및 관리하기
- DI를 위해서는 객체생성을 해야하는데 Spring Framework(Bean, Spring IoC)에서 그 역할을 대신 해준다.
Bean은 스프링이 관리하는 객체를 의미하고,
Spring IoC는 그런 Bean을 모아둔 통이라고 생각하면 된다.
============================================================================================
위 포스트에서 요점요약
객체를 생성하는 클래스가 객체를 부르는 클래스에 의해서 통제되면 강한결합 그것을
DI(의존성 주입)을 통해
객체를 부르는클래스 객체 생성클래스를 통제한다
부르는 클래스에서
파라미터에 클래스와 객체를넣고
맴버변수 private final 을 사용함으로써
새로운 객체를 생성하는 것이아니라
이렇게 하여
객체를 부르는 클래스가 통제되는것이다
이것을
IoC (inversion of control: 제어의 역전)
이라고 부르는것이다
강의에서는 가위를 예시로 들었는데
- 용도에 맞게 필요한 객체를 그냥 가져다 사용
- "DI (Dependency Injection)" 혹은 한국말로 "의존성 주입"이라고 부릅니다.
- 사용할 객체가 어떻게 만들어졌는지는 알 필요 없음
- 실생활 예제) 가위의 용도별 사용
- 음식을 자를 때 필요한 가위는? → 부엌가위 (생성되어 있는 객체 kitchenScissors)
- 무늬를 내며 자를 때 필요한 가위는? → 핑킹가위 (생성되어 있는 객체 pinkingShears)
- 정원의 나무를 다듬을 때 필요한 가위는? → 전지가위 (생성되어 있는 객체 pruningShears)
이것이 프로그램의 유지보수에 더 효율적이다.
문제는...
가위로 예시를 들면 가위를 쓰기전에 가위를 만들어 놓아야 필요할때 가위를 쓸수있다
하지만 스프링은 객체를 쓰지않으면 미리 객체를 생성해두지않는다
그렇기 위해
빈!BEAN
을 사용한다 미리 스프링에서 생성해놓고 관리하는 객체들을 의미한다
스프링은 이것을 Ioc 컨테이너에 넣어놓고 보관한다
이러한 모양이 스프링에서 빈을 관리하고있다! 이런 표시이다
@Component를 이용하면
스프링에서 빈을 생성하고 Ioc컨테이너에 넣어준다!
그 빈은
@Autowired 를 사용하여 이용할수있다!
Lombok 의 @RequiredArgsConstructor 는 이것을 생략하여 사용할수있게해준다
'Stack > Spring' 카테고리의 다른 글
인텔리제이 브레이크포인트와 디버거를 통해 오류 해결하기 (0) | 2022.06.06 |
---|---|
MVC 패턴 이해와 사용법 (0) | 2022.06.05 |
MVC 패턴,Controller & Servicec & Repository 개념 (0) | 2022.05.28 |
<aside> restAPI의 put 과 patch 는 어떤 차이점이 있을까요? 어떤 경우에 사용하면 좋을까요?</aside> (0) | 2022.05.26 |
spring (controller,service,repository) (0) | 2022.05.26 |