스프링은 특정한 하나가 아니라 여러가지 기술들의 모음
(스프링 프레임워크, 스프링 부트, 스프링 데이터, 스프링 세션, 스프링 시큐리티, 스프링 Rest Docs, 스프링 배치, 스프링 클라우드 등)
빌드하고 서버 띄우는 것 까지 자체적으로 가능
어떤 라이브러리를 사용할 때 해당 라이브러리와 관련있는 다른 라이브러리들도 함께 가져옴
외부 라이브러리 버전을 알아서 지정
필요할때만 커스텀
- 스프링은 자바 언어 기반의 프레임워크
- 자바 언어의 가장 큰 특징 - 객체 지향 언어
- 스프링은 객체 지향 언어가 가진 강력한 특징을 살려내는 프레임워크
- 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크
객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만듦
컴포넌트를 쉽고 유연하게 변경하면서 개발할 수 있는 방법 -> 다형성
유연하고 변경에 용이
구현보다 인터페이스가 먼저!
인터페이스를 구현하면 무한대로 확장 가능
- 다형성이 가장 중요
- 스프링은 다형성을 극대화해서 이용할 수 있게 도와줌
- 스프링에서 이야기하는 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원
변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것
문제점
MemberRepository m = new MemoryMemberRepository(); //기존 코드
MemberRepository m = new JdbcMemberRepository(); //변경 코드
//인터페이스 참조변수에 인터페이스를 구현한 클래스 객체를 넣는 중
기능에 맞게 적당한 크기로 나누는 것이 좋음
중요한 원칙
프로그래머는 추상화에 의존해야지, 구체화에 의존하면 안됨
클라이언트 코드가 구현 클래스(구현)에 의존하지 말고, 인터페이스(역할)에 의존해야함
클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있고, 구현체에 의존하게 되면 변경이 아주 어려워짐
OCP에서 설명한 MemberService는 인터페이스에 의존하지만, 구현 클래스도 동시에 의존하기 때문에 DIP 위반
MemberRepository m = new MemoryMemberRepository(); //기존 코드
MemberRepository m = new JdbcMemberRepository(); //변경 코드
//MemberService 클라이언트가 구현 클래스를 직접 선택
정리
- 객체 지향의 핵심은 다형성
- 다형성 만으로는 쉽게 부품을 갈아 끼우듯이 개발할 수 없음
- 다형성 만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경됨
- 다형성 만으로는 OCP, DIP를 지킬 수 없음 -> 뭔가 더 필요
의존 관계 주입, 의존성 주입
자바 객체들을 컨테이너 안에 넣어놓고 이 안에서 의존관계를 연결하고 주입
제공 정리
- 모든 설계에 역할과 구현을 분리하자
- 역할만 만들어두고, 구현은 언제든지 유연하게 변경할 수 있도록 만드는 것이 좋은 객체 지향 설계
구현기술이 바뀌더라도 나머지를 변경 할 필요가 없어서 변경의 범위가 작고 유연해짐
- 이상적으로는 모든 설계에 인터페이스를 부여하자
- 실무적으로는 인터페이스를 도입하면 추상화라는 비용이 발생하기 때문에
기능을 확장할 가능성이 없다면 구체 클래스를 직접 사용하고, 향후 꼭 필요할 때 리팩터링해서 인터페이스를 도입하는 것도 방법