1. 오브젝트와 의존관계
자바 → 객제지향 프로그래밍
스프링은 오브젝트에 가장 관심을 둔다. 애플리케이션에서 오브젝트가 생성되고 다른 오브젝트와 관계를 맺고, 사용되고, 소멸하기까지의 전 과정 고려해야 함
객체지향 설계의 기초와 원칙을 비롯해 디자인 패턴, 리팩토링, 단위테스트 같은 오브젝트 설계와 구현에 대해 배울 것
관심사의 분리
- 분리와 확장을 고려한 설계
- 개방폐쇄 원칙
관심사 분리 기법
- 메소드 추출 기법 이용해서 리팩토링
- 상속을 통한 확장
→ 클래스 계층 구조를 통해 두 개의 관심이 독립적으로 분리 → 확장 용이
템플릿 메소드 패턴
슈퍼클래스에 기본적인 로직을 만들고, 그 기능의 일부를 추상 메소드나 오버라이딩이 가능한 protected 메소드 등으로 만든 뒤 서브클래스에서 이러한 메소드를 필요에 맞게 구현해서 사용하도록 하는 방법
팩토리 메소드 패턴
서브클래스에서 구체적인 오브젝트 생성 방법을 결정하게 하는 것. 템플릿 메소드와는 오브젝트 생성 방식의 차이
💡상속구조를 통해 성격이 다른 관심사항을 분리한 코드를 만들어내고, 서로 영향을 덜 주도록 했는지?
템플릿 메소드 패턴과 팩토리 메소드 패턴의 한계
상속을 사용
- 이미 다른 목적을 위해 상속을 사용하고 있을 수 있음
- 상속을 통한 클래스 간의 관계가 지나치게 밀접
- 이미 확정되어 있으므로 확장된 기능을 생성하는 코드를 다른 서비스에 적용하기 어려움
관심사 간의 변화의 성격이 다르다는 건 변화의 이유와 식, 주기 등이 다르다는 뜻.
클래스의 분리
단점
ConnectionMaker 객체와 메소드명이 변경될 경우 실제 호출부를 지나치게 많이 변경해야 한다.
근본원인
ConnectionMaker를 호출하는 UserDao가 바뀔 수 있는 정보, 즉 DBConnection을 제공하는 클래스가 어떤 것인지에 대해 너무 많이 알고 있다.
인터페이스의 도입
두 개의 클래스가 서로 긴밀하게 연결되어 있지 않도록 중간에 추상적인 느슨한 연결고리를 만들어주는 것
관계설정 책임의 분리 / IoC
클래스가 아닌 오브젝트-오브젝트 관계를 설정
클래스 사이의 관계: 코드에 다른 클래스 이름이 등장
오브젝트 사이의 관계: 런타임 시에 한쪽이 다른 오브젝트의 ref를 가지고 있는 경우 → spring bean 의존, 다이나믹. 다형성.
UserDao가 어떤 ConnectionMaker를 생성할지 UserDao의 클라이언트로 하여금 결정하게 한다.
개방폐쇄원칙
클래스나 모듈은 확장에는 열려 있어야 하고 변경에는 닫혀 있어야 한다.
인터페이스를 사용해 확장 기능을 정의한 대부분의 API는 개방폐쇄원칙을 따른다고 할 수 있다.
높은 응집도 변화가 일어날 때 해당 모듈에서 변하는 부분이 크다는 것
낮은 결합도 책임과 관심사가 다른 오브젝트 또는 모듈과는 느슨한 연결관계만 간접적으로 만들어 주는 것. 결합도
- 변화에 대응하는 속도가 높아진다.
- 구성이 깔끔
- 확장에 편이
결합도 하나의 오브젝트가 변경이 일어날 때에 관계를 맺고 있는 다른 오브젝트에게 변화를 요구하는 정도
객체지향설계원칙(SOLID)
- SPR(The Single Responsibility Principle): 단일 책임 원칙
- OCP(The Open Closed Principle): 개방폐쇄원칙
- LSP(The Liskov Subtitution Principle): 리스코프 치환 원칙
- ISP(The Interface Segregation Principle): 인터페이스 분리 원칙
- DIP(The Dependency Inversion Principle): 의존관계 역전 원칙
전략패턴
context에서 변경될 수 있는 로직을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 클래스를 필요에 따라 선택해 사용할 수 있게 하는 디자인 패턴.
IoC
팩토리
객체의 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 돌려준다.
컴포넌트 애플리케이션의 핵심적인 데이터 로직과 기술 로직 담당
설계도 애플리케이션의 오브젝트들을 고성하고 그 관계를 정의하는 책임
제어의 역전 IoC
- 모든 제어 권한을 자신이 아닌 다른 대상에게 위임
- 제어권을 상위 템플릿 메소드에 넘기고 자신은 필요할 때 호출되어 사용하도록 한다는 개념
- 프레임워크 애플리케이션 코드가 프레임워크에 의해 사용
- 라이브러리 라이브러리를 사용하는 코드가 애플리케이션 흐름을 직접 제어
- 프레임워크, 또는 컨테이너와 같이 애플리케이션 컴포넌트의 생성과 관계설정, 사용, 생명주기 관리 등을 관장하는 존재 필요
스프링의 IoC
빈 bean
- 스프링이 제어권을 가지고 직접 만들어 관계를 부여하는 오브젝트
- EJB와 유사한 오브젝트 단위의 애플리케이션 컴포넌트
- 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트
빈 팩토리
- 빈의 생성과 관계설정 등의 제어를 담당하는 IoC오브젝트
애플리케이션 컨텍스트
- 빈 팩토리의 확장, 스프링의 가장 대표적인 오브젝트 팩토리
- 싱글톤 레지스트리
- 별도의 설정 정보를 참고해 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 범용적 IoC엔진
- 때로는 외부의 오브젝트 팩토리에 그 작업을 위임하고 결과만 받아 사용하기도 함
장점
- 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.
- 오브젝트 팩토리의 갯수가 많아져도 상관 없음
- 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.
- 오브젝트 생성 방식, 후처리, 조합, 설정 다변화, 인터셉팅 등 다양한 기능 제공
- 애플리케이션 컨텍스트는 다양한 DL 제공
서버 애플리케이션과 싱글톤
싱글톤 오브젝트를 애플리케이션의 생명주기 중 딱 한 번 만들어 사용하는 방식
서블릿 멀티스레드 환경에서 싱글톤으로 동작. 서블릿 클래스당 하나의 오브젝트만 만들어 두고, 요청을 담당하는 여러 스레드에서 해당 오브젝트를 공유해 동시에 사용
싱글톤 구현의 한계
- private 생성자를 갖고 있기 때문에 상속할 수 없다.
- 테스트의 어려움
- 서버환경에서는 싱글톤이 하나만 만들어지는 것을 보장하지 못한다.
- 클래스로더의 구성, 혹은 JVM 여러개에 분산 설치 되는 경우 싱글톤을 보장할 수 없음
- 전역 상태를 만들 수 있기 때문에 바람직하지 않다.
싱글톤 레지스트리
스프링이 제공하는, 싱글톤 형태의 오브젝트를 만들고 관리하는 기능
평범한 자바 클래스를 싱글톤으로 사용 가능
싱글톤 방식으로 사용된 애플리케이션 클래스도 public 가능
싱글톤 패턴과 달리, 싱글톤 레지스트리를 사용하면 스프링이 지향하는 객체지향적 설계 방식과 원칙, 디자인 패턴 등을 적용하는 데에 아무런 제약이 없다.
싱글톤과 오브젝트의 상태
싱글톤은 멀티스레드 환경이라면 여러 스레드가 동시에 접근해서 사용할 수 있다.
싱글톤이 멀티스레드 환경에서 서비스 형태의 오브젝트로 사용되는 경우에는 stateless 방식으로 만들어져야 한다.
메소드 파라미터나, 메소드 안에서 생성되는 로컬 변수는 매번 새로운 값을 저장할 독립적인 공간이 만들어지기 때문에 싱글톤이라고 해도 여러 스레드가 변수의 값을 덮어쓸 일은 없다.
단순한 readonly라면 static final이나 final로 선언하는 편이 나음
스프링 빈의 스코프
singleton 스프링 컨테이너 내에 한 개의 오브젝트만 만들어져서, 강제로 제거하지 않는 한 스프링 컨테이너가 존재하는 동안 계속 유지
prototype 컨테이너에 빈을 요청할 때마다 새로운 오브젝트 생성
request 웹을 통해 새로운 http 요청이 생길 때마다 생성
session 웹의 세션과 유사한 스코프
DI
의존관계는 방향성을 가진다.
의존 오브젝트 오브젝트가 만들어지고 나서 런타임 시 의존관계를 맺는 대상
의존관계 주입의 조건
설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재가 있다는 것
- 관계설정 책임을 가진 코드를 분리해서 만들어진 오브젝트
- ex) 스프링의 애플리케이션 컨텍스트, 빈 팩토리, IoC 컨테이너 등
의존관계 주입DI와 의존관계 검색DL
DI DI를 적용하려면 자신도 컨테이너가 관리하는 빈이어야 한다.
DL 검색하는 오브젝트는 자신이 스프링의 빈이 아니어도 된다.
DI의 방법
- 수정자 메소드를 이용한 주입
- 일반 메소드를 이용한 주입
토비의 스프링 3.0
'Web > Spring' 카테고리의 다른 글
[Custom datasource] hikary.jdbc-url 쓰다가 Failed to configure a DataSource: 'url' 발생 (0) | 2021.11.06 |
---|---|
[Swagger] Swagger2 2.xx 버전오류 (0) | 2021.11.02 |
[Spring] OXM, 서비스 추상화, 빈 애노테이션, @Import, @Profile, @Enable* (0) | 2021.10.29 |
[Spring] 프록시, AOP, 트랜잭션 (0) | 2021.10.29 |
[Spring] 테스트, 템플릿, 예외 (0) | 2021.10.29 |
댓글