티스토리 뷰
📌 목차
1️⃣ 의존 관계
2️⃣ 의존 역전
3️⃣ 의존 주입 패턴
4️⃣ 의존성을 주입 해주는 주체
1️⃣ 의존 관계
💁🏻♀️ 의존이 뭔데?
💡 한쪽(B)의 변경사항이 다른 한쪽(A)에도 영향을 미칠 때, A는 B에 의존한다고 말함
🔎 의존 관계가 형성되는 경우
: 어떤 클래스가 다른 클래스(or 인터페이스)를 사용할 때
(1) 다른 클래스의 레퍼런스 변수를 사용하는 경우 (ex. B b;)
public class A {
private B b;
}
(2) 다른 클래스의 인스턴스를 생성하는 경우 (ex. new B())
public class A {
private InterfaceB b = new B(); // B는 InterfaceB 인터페이스를 구현
}
(3) 다른 클래스를 상속받는 경우
public class A extends B {}
❗ 인터페이스로 의존관계를 맺어서 의존 관계를 약하게하자! (더 객체지향적)
❗ 의존 관계는'객체-객체'뿐만이 아니라 '메서드-필드' 사이에도 형성!
→ 메서드가 필드에 대해 자세하게 알고 있다면 강하게 의존하고 있는 상태 (캡슐화를 하자)
💬 유지보수하기 좋은 의존 관계는 어떻게 형성되어야 하는가?
2️⃣ 의존 역전
: 고수준 컴포넌트가 저수준 컴포넌트에 의존하지 않도록 의존 관계를 역전 시키는 것
- 컴포넌트 : 여러 개의 프로그램 함수들을 모아 하나의 특정한 기능을 수행할 수 있도록 구성한 작은 기능적 단위 (ex. 클래스)
- 고수준 : 구체적인 기술에 종속❌ (x. Service 계층)
- 저수준 : 구체적인 기술에 종속⭕ (ex. Repository 계층)
👩🏻🏫 인터페이스를 사용해서 의존관계를 역전하자 (의존 방향이 인터페이스에 모이도록!)
Controller 표현계층
Service 애플리케이션 계층
Repository(interface) 도메인 계층
Repository(구체 클래스) 인프라스트럭처 계층
3️⃣ 의존 주입 패턴
💁🏻♀️ 인터페이스를 통해 의존관계를 역전했다면, 인터페이스에 구현체는 누가, 어떻게 넣어주지?
💡 외부(ex. Spring, Client)에서 구현체의 인스턴스를 생성 후 주입 해줘야 함! (컴포넌트에서 직접❌)
🔎 의존 주입 패턴의 장점
✔️ 테스트가 용이해짐!
📎 (참고) Test Double - 테스트 코드를 실행하기 위한 대여 클래스
✔️ 어떤 구현체 사용할지 코드 수정 없이, 실행 시점(Runtime)에 지정할 수 있음
4️⃣ 의존성을 주입 해주는 주체
🖐🏻 먼저, 스프링프레임 워크에 대해서 알아보자!
- 스프링 프레임워크에는 프로젝트에서 사용할 구현체의 인스턴스(빈)를 생성 / 등록해서 필요한 곳에 주입해주는 애플리케이션 컨텍스트(IoC Container, Bean Factory)가 존재!
- 빈(Bean)은 기본적으로 싱글턴 (동일 타입의 인스턴스는 하나만 생성)
- 프로젝트의 모든 클래스가 빈(Bean)이 되는 것은 아님 (특정 애너테이션(ex. @RestController, @Component)이 붙은 클래스만!)
- 스프링은 빈으로 등록된 클래스만 의존성 주입에 사용할 수 있음!
💁🏻♀️ 빈은 왜 싱글턴으로 설계 되었나요?
💡 클라이언트 코드는 프로젝트의 클래스들 속에서 오직 메서드만 활용하기 때문 (❗동기화 문제 때문에 그렇게 해야만 함)
🔎 스프링 프레임워크에서 빈(Bean)을 주입해주는 방식
✔️ 실행하는 시점에 적절한 빈을 선택해보자 - Spring Profile
즉, DB Repository와 File Repository 중에서 어떤 클래스(빈)을 Repository인터페이스의 구현체로 사용할 지 프로그램이 시작하는 시점에 결정하자
@Profile("prod")
@Component
public class DatabaseRepository implements Repository { ... }
@Profile("test")
@Component
public class FileRepository implements Repository { ... }
이렇게 설정만 해주면 ↓ 아래와 같이 실행을 prod, test 중 어떤 것으로 할지 결정 후 실행 가능!
java -jar target/프로젝트명.jar --spring.profiles.active=prod
❕ (참고) jar파일 만드는 법
(1) 오른쪽 사이드 바에서 Maven(clean 누르기, skip test 선택) > package
(2) /target 디렉토리에서 .jar 파일 확인
✔️ 실행하는 중 적절한 빈을 선택해보자 - Spring Profile
즉, DB Repository와 File Repositor가 모두 빈으로 등록되어 있을 때, 프로그램 실행 중 적절한 클래스(빈)을 Repository인터페이스의 구현체로 사용하자!
@Order(0)
@Component
public class DatabaseRepository implements Repository { ... }
@Order(1)
@Component
public class FileRepository implements Repository { ... }
@Component
public class Service {
private Repository inUseRepository;
private Repository spareRepository;
public Service(List<Repository> repositorise) {
inUseRepository = repositorise.get(0);
spareRepository = repositorise.get(1);
}
public void changeRepository() { // 구현체 변경하기
Repository tempRepository = this.inUseRepository;
inUseRepository = spareRepository;
spareRepository = tempRepository;
}
}
'데브코스 > 1주차 - 프레임워크를 위한 JAVA' 카테고리의 다른 글
Chapter06 구현된 걸 사용하게 되는 패턴 (0) | 2023.09.25 |
---|---|
Chapter05 직접 구현하게 되는 패턴 (0) | 2023.09.25 |
Chapter04 SOLID (0) | 2023.09.24 |
Chapter02 객체지향적인 코드 작성 (0) | 2023.09.22 |
Chapter01 객체지향 관련 문법 정리 (0) | 2023.09.20 |