인프런의 블랙 프라이데이 할인을 맞아 Spring의 기본 개념을 다시 잡기 위해 강의를 구매하였다.
강의를 들으면서 다시 한번 기본 개념을 학습하고 나만의 방식으로 정리해보고자 한다.
Spring 프레임워크 와 Spring Boot
1. Spring 프레임워크
핵심 기술을 기반으로 한 여러가지 기술들을 모아놓은 것
셋팅만 잘된다면 편리하게 사용 할 수 있지만 이 셋팅 자체에 많은 시간이 들어간다.
2. Spring Boot
스프링을 편리하게 사용할 수 있도록 지원한다.
앞서 설명했듯이 Spring 프레임워크만 사용하는 경우 셋팅 자체에 많은 시간을 할애해야 하기 때문에 최근에는 필수적으로 사용 되는 편
빌드나 라이브러리 버전 등 편의성에 초점이 맞추어져 있다.
다만, 편의성에 초점이 맞춰진 만큼 Spring Boot 단일로는 사용이 불가능하다.
(물론 Spring Boot를 쓰면 자동으로 Spring을 가져온다.)
Spring의 핵심 컨셉
Spring은 자바 언어 기반의 프레임 워크이다.
자바 언어의 가장 큰 특징은 객체 지향 언어라는 점이기 때문에 Spring은 이런 객체 지향 언어의 특징을 잘 살려낼 수 있도록 설계 되어 있다.
객체 지향 프로그래밍이란?
컴퓨터 프로그램을 각각의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는것.
각각의 객체는 메시지를 주고 받거나 데이터를 처리하는 등 협력할 수 있다.
이런 객체 지향 프로그래밍은 프로그램은 유연하고 변경이 용이하게 만든다.
흔히, 객체 지향의 특징은 이른바 캡상추다로 불리는 특징들로 정리할 수 있다.
- 캡슐화
- 상속
- 추상화
- 다형성
이 4가지 특징들이 객체 지향을 대표하는 단어라고 할 수 있는데, 그중에서도 다형성의 특징 덕에 유연한 프로그래밍이 가능해 지는 것.
다형성
역할과 구현을 나눠 놓은 것.
예를 들어 버스라는 역할이 있다고 할때 구현은 각 버스 번호가 될 것이다.
우리는 버스를 이용할 때, 1번 버스든 100번 버스든 1000번 버스든 버스가 어떻게 움직이는지 알 필요가 없다.
내가 가는 방향과 맞는 버스를 이용하면 되기 때문이다.
또한, 만약에 새로운 노선이 추가 된다면 1001번 버스를 만들면 된다.
즉, 버스라는 역할이 변하는 것은 아니기 때문에 새로운 노선을 추가하거나 노선이 변경된다 하더라도 버스를 이용하는데 불편함이 없는 것이다.
이렇게 되면 버스 노선을 아주 간편하게 무한히 확장할 수 있다.
그럼 프로그래밍을 할때 역할을 인터페이스라고 하고 구현을 구현체라고 생각해보자.
우리는 인터페이스를 먼저 구현하고 필요한 구현체를 만들면 손쉽게 변경과 확장이 가능하게 된다.
다만, 인터페이스 자체가 변하면 클라이언트, 서버 모두에 큰 변경이 발생하기 때문에 초기 설계에서 인터페이스를 안정적으로 잘 설계하는 것이 매우 중요하다.
좋은 객체 지향 설계의 5가지 원칙(SOLID)
- SRP : 단일 책임 원칙(Single Responseibility Princile)
- OCP : 개방 - 폐쇄 원칙 (Open/closed Principle)
- LSP : 리스코프 치환 원칙 (Liskob Substitution Principle)
- ISP : 인터페이스 분리 원칙 (Interface segrergation Principle)
- DIP : 의존관계 역전 원칙 (Dependency inversion Principle
1. SRP
하나의 클래스가 하나의 책임만 가지게 하는것.
가장 중요한 기준은 변경이다.
변경시에 파급 효과가 적으면 해당 원칙을 잘 따른 것.
2. OCP
소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다.
이를 수행하기 위해선 다형성의 활용이 필요하다.
예를 들어, 인터페이스를 구현한 새로운 클래스를 하나 만들어 새로운 기능을 구현하는 것
OCP의 문제점
구현 객체를 변경하려면 클라이언트의 코드를 변경해야 하기 떄문에 OCP 원칙을 지킬 수 없다.
이를 해결하려면 연관관계를 맺어주는 별도의 조립, 설정자가 필요한데 이것을 Spring에서 도와준다.
3. LSP
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 한다.
어떤 인터페이스와 구현체가 있을때 기능적으로 보장을 해야하는 것.
좀 더 쉽게 말하자면 값을 +하는 기능이 있을때 얼마를 + 시키는지 변경 시키는 것은 상관 없지만 -시키는 기능이 들어오면 해당 원칙을 깨뜨리는 것이 된다.
4. ISP
특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
인터페이스를 좀더 작은 기능기능 별로 분리하는 것.
이렇게 하면 인터페이스가 명확해지고 대체 가능성을 높일 수 있다.
5. DIP
클라이언트가 인터페이스 의존하도록 설계하라는 의미
역할에 의존해야지 구현에 의존하게 되면 수정이 어려워 지기 때문이다.