스프링이란?
- 자바 언어 기반의 프레임워크
- 스프링 프레임워크 + 스프링 부트
- 스프링 데이터, 스프링 시큐리티, 스프링 세션 등
- 핵심 기술
- 스프링 DI 컨테이너, AOP, 이벤트, 기타
- 웹 기술
- 데이터 접근 기술
- 테스트
- 스프링 부트?
- 스프링을 편리하게 사용할 수 있도록 지원, 단독으로 실행 가능하도록
- Tomcat 같은 웹 서버 내장
- 외부 라이브러리, 버전 호환성을 자동으로 관리해줌
- 자바 언어의 객체 지향적 특징을 살릴 수 있도록 만든 프레임워크
- 즉, 좋은 객체 지향 애플리케이션을 만들 수 있게 해줌
객체 지향의 특징?
- 추상화, 캡슐화, 상속, 다형성
- 프로그램을 독립된 단위(객체)들의 모임으로 보고, 객체들 간의 메시지 교환, 데이터 처리로 프로그램을 구성하는 것
- 프로그램을 유연하고 변경이 용이하도록 만듬
- 이건 다형성의 특징을 말하는 것
- 역할(인터페이스)과 구현(구현체)을 구분하여 사용자는 인터페이스에만 의존을 하도록 함
- 따라서 구현체는 유연하게 변경되어도 사용자는 무관
- 사용자는 대상의 역할(인터페이스)만 알면 됨
- 클라이언트는 구현 대상(구현체)의 내부 구조를 몰라도 되고, 내부 구조가 변경되더라도 영향을 받지 않음
- 구현 대상(구현체) 자체를 변경해도 영향을 받지 않아야 함
public interface MemberRepository {}
public class MemberMemberRepository implements MemberRepository {}
public class JdbcMemberRepository implements MemberRepository {}
public class MemberService {
//private MemberRepository memberRepository = new MemoryMemberRepository();
private MemberRepository memberRepository = new JdbcMemberRepository();
}
- 즉, 다형성의 본질은?
- 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있음
- 다형성의 한계는?
- 역할(인터페이스) 자체가 변경되면 구현(구현체)도 모두 수정되어야 함
스프링과 객체 지향
- 객체 지향의 다형성이 가장 중요하고, 스프링은 이 다형성을 극대화해서 이용할 수 있도록 해줌
- 제어역전(IoC), 의존관계 주입(DI) 모두 다형성을 활용한 것
객체 지향 설계의 5원칙
SOLID
- SRP : 단일 책임 원칙 (Single Responsibilty Principle)
- 한 클래스는 하나의 책임만을 가짐
- 변경이 있을 때 파급 효과가 적어야 한다는 뜻
- OCP : 개방-폐쇄 원칙 (Open/Closed Principle), 가장 중요
- 확장에는 열려있고, 변경에는 닫혀 있어야 한다는 것 -> 다형성, 위의 코드 참고
- 구현체를 변경하려면 결국 클라이언트(MemberService)를 수정해야 함 -> OCP 원칙 위배
- 객체를 생성하고 연관관계를 맺어주는 설정자가 필요 -> 스프링의 DI, IoC로 해결
- LSP : 리스코프 치환 원칙 (Liskov Substitution Principle)
- 프로그램의 객체는 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 함
- 즉, 다형성에서 하위 클래스는 인터페이스의 규약을 다 지켜야 한다는 것
- ISP : 인터페이스 분리 원칙 (Interface Segregation Principle)
- 특정 클라이언트 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
- e.g. 자동차 인터페이스 -> 운전 인터페이스 + 정비 인터페이스
- 인터페이스가 명확해지고, 대체 가능성이 높아짐
- DIP : 의존관계 역전 원칙 (Dependency Inversion Principle)
- 추상화에 의존하고, 구체화에 의존해선 안된다
- 즉, 구현 클래스에 의존하지 않고 인터페이스에 의존해야 한다
- 위의 예제 코드에서 MemberService는 DIP 원칙을 위배함
- 클라이언트가 구현 클래스를 직접 선택 -> DIP 위반
MemberRepository m = new MemoryMemberRepository();
정리
- 객체 지향의 핵심은 다형성
- 다형성 만으로는 OCP, DIP 원칙을 지킬 수 없음
- 즉, 클라이언트 코드와 구현 객체를 완전히 분리가 불가능
- 이걸 해결해주는게 스프링 프레임워크
객체 지향 설계와 스프링
- 스프링에서 다형성 + OCP, DIP를 가능하게 지원하는 방법?
- DI(Dependency Injection) : 의존관계, 의존성 주입
- DI 컨테이너 제공
- 클라이언트 코드의 변경 없이 기능 확장이 가능하고, 쉽게 부품 교체하듯이 개발이 가능함