스프링 핵심 원리 - 기본편의 복습을 위한 글이며,
이 글에 나오는 모든 소스코드의 저작원은 인프런의 김영한 강사님께 있습니다.
1. Spring?
Spring이 무엇인가에 대하여 설명하기 앞서, Framework의 개념부터 살펴보겠다.
1.1 Framework
FrameWork란 어플리케이션 개발에 바탕이 되는 템플릿과 같은 역할을 하는 클래스들과 인터페이스의 집합이다. 즉, 프로그램의 전체적인 구조와 흐름을 확정지으며, 프로그래머가 정의해야할 메소드의 이름까지 결정짓는 역할까지 한다.
1.2 Spring Framework
Spring도 마찬가지로 프레임워크의 한 종류이다. 스프링 공식 규격에 따르면 Spring Framework는 자바 플랫폼을 위한 오픈소스 애플리케이션 프레임워크로서 엔터프라이즈급 애플리케이션을 개발하기 위한 모든 기능을 종합적으로 제공하는 경량화된 솔루션이다.
- 엔터프라이즈급 개발 : 대규모 데이터 처리와 트랜젝션이 동시에 여러 사용자로부터 행해지는 매우 큰 규모의 환경
Spirng Framework는 경량 컨테이너로 자바 객체를 담고 직접 관리한다. 객체의 생성 및 소멸 그리고 라이프 사이클을관리하며 언제든Spring 컨테이너로 부터 필요한 객체를 가져와 사용할 수 있다.
스프링의 진짜 핵심은 자바 언어 기반의 프레임워크라는것이다. 자바 언어의 가장 큰 특징은 객체 지향 언어로서, 스프링은 객체 지향 언어가 가진 강력한 특징을 잘 살려낼 수 있다.
즉, 스프링은 좋은 객체 지향 어플리케이션을 개발할 수 있게 도와주는 프레임워크라고 할 수 있다.
1.3 Spring Framework vs. Spring Boot
흔히들 스프링 공부를 시작할 때 스프링 프레임워크와 스프링 부트를 많이 헷갈려하곤 한다. 간혹 둘을 전혀 새로운 기술로 생각하시는 분들도 있다. 그러나, 스프링 부트는 스프링 프레임워크에 속하는 큰 도구이며, 스프링을 편리하게 사용할 수 있도록 지원하는 시스템이다.
"스프링과 스프링 부트의 차이점"
1. 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성시켜 준다.
2. Tomcat같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 된다.
3. 손쉬운 빌드 구성을 위한 Starter 종속성을 제공한다.
4. 메트릭, 상태 확인, 외부 구성 같은 프로덕션 준비 기능을 제공한다.
5. 스프링과 3rd path(외부) 라이브러리를 자동으로 구성해준다.
2. 객체 지향 프로그래밍
객체 지향의 특징으로는 다음 4가지가 있다.
- 추상화
- 캡슐화
- 다형성
- 상속
객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 객체들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고 받고, 데이터를 처리할 수 있다. (= 협력)
또한, 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 많이 사용된다.
2.1 유연하고 변경이 용이하다?
연하고 변경이 용이하다는 것은 컴퓨터 부품을 갈아 끼우듯이 컴포넌트를 쉽고 유연하게 변경하면서 개발할 수 있는 방법이다. 유연하고 변경이 용이하게 하는 것이 객체 지향 프로그래밍의 특징인 다형성이다.
객체 지향 프로그래밍의 다형성이라는 특징은 프로그래밍을 '역할'과 '구현'으로 구분해준다.
2.2 역할과 구현을 분리하자.
역할과 구현을 분리하는 것은 자바 언어의 다형성이 핵심이다. 자바 언어의 다형성을 활용하면
역할 = 인터페이스
구현 = 인터페이스를 구현한 클래스, 구현 객체
으로 나눌 수 있다.
또한, 객체를 설계할 때 역할과 구현을 명확히 분리해야 하며 객체 설계시 역할(인터페이스)을 먼저 부여하고, 그 역할을 수행하는 구현 객체를 만들어야 한다. 혼자 있는 객체는 없으며, 수 많은 객체 클라이언트와 객체 서버는 서로 협력 관계를 가진다는 개념이 중요하다.
2.3 다형성의 본질
다형성을 잘 이용하면, 인터페이스(역할)를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다. 따라서, 다형성의 본질을 이해하려면 협력이라는 객체 사이의 관계가 중요하다 할 수 있다.
즉, 다형성의 본질은 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다는 것이다.
2.4 스프링과 객체 지향
스프링에서는 앞서 말했듯이 다형성이 가장 중요하다. 또한 스프링은 다형성을 극대화해서 이용할 수 있게 도와준다.
스프링에서 이야기하는 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다.
3. 좋은 객체 지향 설계의 5가지 원칙(SOLID)
3.1 SRP(Single Reponsiblity Principle) : 단일 책임 원칙
- 한 클래스는 하나의 책임만 가져야 한다.
- 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것이다.
3.2 OPC(Open/Closed Principle) : 개방-폐쇄 원칙
- 소프트웨어 요소는 확장에는 열려 있으나, 변경에는 닫혀 있어야 한다.
- 다형성을 활용.
- 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현.
- 역할과 구현의 분리를 생각.
개방-폐쇄 원칙의 한계
1. 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다.
2. 분명 다형성을 사용하였지만 OCP원칙을 지킬 수 없다.
3.3 LSP(Liskov Substitution Principle) : 리스코프 분리 원칙
- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
- 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것, 다형성을 지원하기 위한 원칙, 인터페이스를 구현한 구현체는 믿고 사용하려면 이 원칙이 필요하다.
3.4 ISP(Interface Segregation Principle) : 인터페이스 분리 원칙
- 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
- 인터페이스가 명확해지고, 대체 가능성이 높아진다.
- 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리.
- 사용자 인터페이스 -> 운전자 클라이언트, 정비사 클라이언트로 분리.
- 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않는다.
3.5 DIP(Dependency Inversion Principle) : 의존관계 역전 원칙
- 프로그래머는 "추상화에 의존해야지, 구체화에 의존하면 안된다."
- 의존성 주입은 이 원칙을 따르는 방법 중 하나이다. 쉽게 이야기해서 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻이다.
- 앞서 이야기한 역할(Role)에 의존하게 해야 한다는 것과 같다. 객체 세상도 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다. 구현체에 의존하게 되면 변경이 아주 어려워진다.
감사합니다 :)
'Backend > Spring - Core' 카테고리의 다른 글
| Spring #4. 스프링 컨테이너와 스프링 빈 (0) | 2022.12.25 |
|---|---|
| Spring #3. 객체 지향 원리 적용 (2) (0) | 2022.12.22 |
| Spring #3. 객체 지향 원리 적용 (1) (0) | 2022.12.22 |
| Spring #2. 스프링 핵심 원리 기본편 - 비즈니스 요구사항과 설계 (1) | 2022.12.21 |
| Spring #0. Annotation (0) | 2022.12.18 |