스프링의 탄생배경
EJB(Enterprise Java Bean) 이란?
JB에 해당하는 Java Bean이란 자바 객체를 재사용 가능하게 컴포넌트화 시킬 수 있는 코딩 방침을 정의한 것을 의미합니다. 즉, EJB는 컴포넌트(빈 혹은 객체)들을 관리하는 컨테이너 라고 이해할 수 있습니다.
EJB 스펙을 지키면서 구현하면 실제 로직보다 EJB 컨테이너를 사용하기 위한 코드들이 많아지는 결과를 발생시켰고,
객체간 의존성을 해결하기 위해서 컨테이너를 개발했는데, 이것이 스프링의 시작입니다.
Spring이란?
스프링은 '여러 기술들의 집합체'로 정의 할 수 있는데 그러한 기술들에는
스프링 프레임워크, 스프링부트, 스프링 데이터 등등.. 이 있습니다.
스프링부트
- 스프링 프레임워크 기반 프로젝트를 복잡한 설정없이 쉽고 빠르게 만들어주는 프레임워크 입니다.
스프링의 핵심으로는 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크라 할 수 있습니다.
객체지향 프로그래밍
객체지향 프로그래밍(OOP)은 "객체"들의 모임으로 파악하고자 하는 것입니다.
이는 프로그램을 유연하고 변경이 용이하게 만들어줍니다.
SOLID - 좋은 객체 지향 설계의 5가지 원칙
- SRP : 단일 책임 원칙 (Single Responsiblity Principle)
- OCP : 개방-폐쇠 원칙 (Open/Closed Principle)
- LSP : 리스코프 치환 원칙 (Liskov Substitution Principle)
- ISP : 인터페이스 분리 원칙 (Interface Segregation Principle)
- DIP : 의존관계 역전 원칙 (Dependency Inversion Principle)
SRP
한 클래스는 하나의 책임만 가져야 한다.
하나의 책임의 기준은 변경이다. 변경이 있을 때 파급 효과가 적어야 단일 책임 원칙을 잘 따랐다고 볼 수 있다.
OCP
확장에는 열려있으나, 변경에는 닫혀있어야한다.
LSP
프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 뜻이다.
ISP
특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 낫다는 원칙
DIP
구체화가 아닌 추상화에 의존하라는 원칙
코드는 인터페이스에 의존하여 작성되어야 한다는 뜻으로, 프로그래머는 구체화가 아닌 추상화에 의존해야 한다는 뜻
객체지향의 핵심은 다형성이다.
그러나 다형성 만으로는 OCP,DIP를 지킬수 없다
이를 해결하기 위해 스프링이 등장했고, 스프링은 DI,DI컨테이너를 통해 다형성 + OCP, DIP를 가능하게 지원한다.
의존관계
"A가 B를 의존한다" 의 뜻은 B가 변경되면 A도 변경된다는 의미이다.
의존관계가 발생하는 상황
A가 B를 의존하는 상황은 다음과 같습니다.
- B가 A의 필드
- B가 A 메서드의 파라미터
- B가 A의 로컬 변수
- B로 메세지를 보냄
public class Barista {
private IceVanillaLatteRecipe iceVanillaLatteRecipe;
public Barista() {
iceVanillaLatteRecipe = new IceVanillaLatteRecipe();
}
}
현재 바리스타는 아이스바닐라라떼 레시피만 만들 수 있습니다.
바리스타가 다양한 커피를 만들 수 있도록 코드를 바꾸면
public class Barista {
private CoffeeRecipe coffeeRecipe;
public Barista(CoffeeRecipe coffeeRecipe) {
this.coffieRecipe = coffieRecipe;
}
}
interface CoffeeRecipe {
}
class IceVanillaLatteRecipe implements CoffeeRecipe {
}
이처럼 의존관계를 인터페이스를 통해 추상화시키면 ,다양한 의존관계를 맺을 수 있다.
즉 실제 구현 클래스와의 관계가 느슨해지고, 결합도가 낮아진다.
정적인 클래스 의존관계
- import 코드만 보고 의존관계를 파악할 수 있는 의존관계
동적인 객체 인스턴스 의존 관계
- 애플리케이션 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존관계
위의 예시에서 실행시점에 Barista의 생성자로 IceVanillaLatteRecipe를 주입함으로써 의존관계를 형성할 수 있다.
의존관계 주입 - DI (Dependency Injection)
- 애플리케이션 실행 시점에 외부에서 실제 구현 객체를 생성하고 이를 의존하는 클래스들에 해당 구현 객체를 연결해 주는 것
public class Application {
public static void main(String [] args) {
CoffeeRecipe recipe = new IceVanillaLatteRecipe();
Barista b = new Barista(recipe); //DI, 의존관계 주입
// ...
}
}
의존 관계 주입을 사용함으로써, 정적인 클래스 의존관계의 변경 없이 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있다.
제어의 역전 - IoC (Inversion of Control)
- 프로그램의 제어 흐름을 개발자가 직접 제어하는 것이 아니라 외부에서 관리하는 것을 의미
예를 들어 스프링을 사용하여 애플리케이션을 실행할 때, 개발자는 아무런 코드를 작성하지 않았는데도 스프링이 내부적으로 다양한 작업들을 진행한다.
쉽게 생각하면 프로그램의 진행 흐름은 이미 만들어져 있으며, 그 사이에 개발자의 코드가 추가되는 것이라 생각할 수 있다.
public class BaristaFactory {
public Barista barista() {
CoffeeRecipe recipe = new IceVanillaLatteRecipe();
Barista b = new Barista(recipe); //DI, 의존관계 주입
return b;
}
}
public class Application {
public static void test(String [] args) {
Barista b = new BaristaFactory().barista(); //IoC 제어의 역전
}
}
원래 Barista가 CoffeRecipe를 결정하고 생성하는 제어권을 가지고 있었으나 지금은 BaristaFactory에게 있다.
자신이 어떤 CoffieRecipe를 만들고 사용할지에 대한 권한을 BaristaFactory에게 넘겼기에, Barista는 이제 수동적인 존재가 된것이다.
이것이 제어의 역전이다.
'🚣활동 > 멋쟁이사자처럼' 카테고리의 다른 글
[멋사 12기 중앙해커톤 참여] (0) | 2024.08.09 |
---|---|
[멋쟁이사자처럼] 4주차 정기세션 (0) | 2024.03.31 |
[멋쟁이사자처럼] 3주차 정기세션 (0) | 2024.03.24 |
[멋쟁이사자처럼] 2주차 정기세션 (0) | 2024.03.14 |
[멋쟁이사자처럼] 1주차 정기세션 - 2 (0) | 2024.03.13 |