스프링의 탄생


스프링의 역사


Java/Kotlin 기반의 웹 프레임워크이다. 로드 존슨(Rod Johnson)이 2002년에 출판한 저서 Expert One-on-One J2EE Design and Development에서 선보인 소스 코드를 시작으로 점점 발전하게 되었다.

'스프링'이라는 이름의 유래는 이전에 Java EE(엔터프라이즈 에디션)의 스펙을 구현한 EJB가 기술의 복잡도가 증가해서 성능이 느렸던 것을 탈피하여, EJB 시절을 “겨울”에 빗대어 겨울 후의 “봄”으로 새로운 시작한다는 것을 의미하는 Spring(봄)이 되었다.


스프링 프레임워크 특징


  • POJO(Plain Old Java Object) 방식 : 다른 클래스나 인터페이스를 상속/implements 받아 메서드가 추가된 클래스가 아닌 getter, setter 같이 기본적인 기능만 가진 자바 객체를 뜻한다. 별도의 프레임워크 없이 Java EE를 사용할 때에 비해 특정 인터페이스를 직접 구현하거나 상속받을 필요가 없어 기존 라이브러리를 지원하기가 용이하고, 객체가 가볍다.

  • 관점 지향 프로그래밍(Aspect Oriented Programming, AOP) : 로깅, 트랜잭션, 보안 등 여러 모듈에서 공통적으로 사용하는 기능을 분리하여 관리할 수 있다.

  • 의존성 주입(Dependency Injection, DI) : 프로그래밍에서 구성요소 간의 의존 관계가 소스코드 내부가 아닌 외부에서 설정을 통해 정의되는 방식이다. 코드 재사용을 높여 소스코드를 다양한 곳에 사용할 수 있으며 모듈간의 결합도도 낮출 수 있다. 계층, 서비스 간에 의존성이 존재하는 경우 스프링 프레임워크가 서로 연결시켜준다.

  • 제어 역전(Inversion of Control, IoC) : 전통적인 프로그래밍에서는 개발자가 작성한 프로그램이 외부 라이브러리의 코드를 호출해서 이용했다. 제어 역전은 이와 반대로 외부 라이브러리 코드가 개발자의 코드를 호출하게 된다. 즉, 제어권이 프레임워크에게 있어 필요에 따라 스프링 프레임워크가 사용자의 코드를 호출한다.

  • 생명주기 관리 : 스프링 프레임워크는 Java 객체의 생성, 소멸을 직접 관리하며 필요한 객체만 사용할 수 있다.


스프링 프레임워크


스프링 프레임워크

- 핵심 기술 : 스프링 DI 컨테이너 / AOP / 이벤트 등
- 웹기술 : 스프링 MVC / 스프링 WebFlux
- 데이터 접근 기술 : 트랜잭션 / JDBC / ORM 등
- 기술 통합 : 캐시 / 이메일 / 스케줄링 등
- 테스트 : 스프링 기반 테스트 지원
- 언어 : 코틀린 / 그루비

스프링 부트

- 스프링을 편리하게 사용할 수 있도록 지원
- 톰캣같은 웹서버를 내장해서 별도의 웹서버 설치 필요 없다
- Starter 종속성 제공 : 라이브러리 사용시 필요한 다른 관련 라이브러리들을 알아서 땡겨준다
- 사용하는 여러 라이브러리들 간의 알맞는 버전 조합을 알아서 세팅해준다
- 관례에 의한 간결한 설정

자바와 스프링


  • 자바 언어의 특징은 객체 지향 언어라는 점이다.

  • 스프링은 객체 지향 언어가 가진 강력한 특징을 살리는 프레임워크이다.


객체지향 프로그래밍


컴퓨터 프로그램을 여러개의 독립된 단위, 객체들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메세지를 주고 받고 데이터를 처리할 수 있다. 유연하고 변경이 용이하게 만들기 때문에 대규모 소프트웨어 개발에 사용한다.


객체 지향 프로그래밍 특징


추상화(abstraction)

객체들의 공통적인 특징(기능, 속성)을 도출하는 것
객체지향적 관점에서는 클래스를 정의하는 것을 추상화라고 할 수 있다.

캡슐화(encapsulation)

실제로 구현되는 부분을 외부에 드러나지 않도록 하여 정보를 은닉할 수 있다.
객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
데이터를 보이지 않고 외부와 상호작용을 할 때는 메소드를 이용하여 통신을 한다. 

상속성(inheritance)

이미 만들어 놓은 상위 객체를 재사용해서 하위 객체를 쉽고 빠르게 만들수 있습니다. 
수정을 할때도 상위객체를 수정해주면 상속받은 모든 하위 객체가 수정이 되므로 유지보수가 쉽다.

다형성(polymorphism)

다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미한다.
부모 클래스 타입의 참조 변수로 자식 클래스 타입의 인스턴스를 참조할 수 있도록 하여 구현한다.

객체 지향 프로그래밍 핵심


역할과 구현을 분리하라! 역할과 구현으로 구분하면 단순, 유연해지며 변경도 편리하다.



  • 클라이언트는 대상의 역할(인터페이스)만 알면 된다.

  • 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.

  • 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.

  • 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.


자바언어의 다형성을 이용해 객체 지향 프로그래밍을 한다.

객체를 설계할 때 역할과 구현을 명확히 분리한다. 객체 설계시 역할을 먼저 부여하고 그 역할을 수행하는 구현 객체를 만든다.


  • 역할 = 인터페이스

  • 구현 = 인터페이스를 구현한 클래스, 객체


다형성의 본질

인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다.
클라이언트를 변경하지 않고 서버의 구현 기능을 유연하게 변경할 수 있다.


좋은 객체 지향 설계 (SOLID)


로버트 마틴이 정리한 좋은 객체 지향 설계의 5가지 원칙


Single Responsibility Principle : 단일 책임 원칙

한 클래스는 하나의 책임만 가져야 한다. 하지만 책임의 범위가 상황에 따라 다르므로 모호하다. 
→ 기준 : 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것이다.

Open Closed Principle : 개방 폐쇄 원칙

소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다. 
다형성을 활용해서 확장하고 기존의 코드는 변경하지 않는다. 
→ 하지만 인터페이스에서 구현 객체를 변경하는 과정에서 코드는 변경된다. 다형성을 사용해도 OCP 원칙이 깨져버린다. 
그래서 객체를 생성하고 연관관계를 맺어주는 별도의 조립, 설정자(스프링 컨테이너)가 필요하다. 

Liskov Substitution Principle : 리스코프 치환 원칙

프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
다형성에서 하위 클래스는 인터페이스 규약을 지켜야 한다는 것이다.
인터페이스를 구현한 구현체를 믿고 사용하기 위한 원칙이다.

Interface Segregation Principle : 인터페이스 분리 원칙

특정 클라이언트를 위한 인터페이스 여러개가 범용(하나로 합친) 인터페이스보다 낫다.
자동차 인터페이스를 운전, 정비 인터페이스로 분리한다. 
분리하면 한쪽 인터페이스 자체가 변해도 다른 쪽에는 영향을 주지 않는다.
→ 인터페이스가 명확해지고, 대체 가능성이 높아진다.

Dependency Inversion Principle : 의존관계 역전 원칙

'추상화에 의존하고 구체화에 의존하면 안된다'의 원칙을 따르는 방법 중 하나이다.
클라이언트가 구현 클래스를 바라보지 말고 인터페이스만 바라보라는 뜻이다. 역할에 의존해야 한다는 것과 같다.

객체 지향의 핵심은 다형성이다. 하지만 다형성 만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다. 그래서 쉽게 부품을 갈아 끼우듯이 개발할 수 없다.
다형성 만으로는 OCP, DIP를 지킬 수 없다.

스프링은 DI(의존성 주입)로 다형성 + OCP, DIP를 가능하게 지원한다.
→ 클라이언트의 코드 변경없이 부품을 교체하듯이 개발한다


애플리케이션 설계의 역할과 구현을 분리해서, 언제든지 구현체는 유연하게 변경할 수 있도록 만드는 것이 좋은 객체 지향설계이다. → 모든 설계에 인터페이스를 부여

하지만 실무적으로 인터페이스를 도입하다보면 추상화라는 비용이 발생한다. 그래서 기능을 확장할 가능성이 없는 경우에는 구현한 클래스를 직접 사용하고, 향후 꼭 필요할 때 리팩토링 해서 인터페이스를 도입하는 방법도 있다.

profile
끊임없이 성장하고 싶은 개발자

0개의 댓글

관련 채용 정보

Powered by GraphCDN, the GraphQL CDN