Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

스프링 핵심 원리 #3

Open
in-seo opened this issue Sep 24, 2022 · 0 comments
Open

스프링 핵심 원리 #3

in-seo opened this issue Sep 24, 2022 · 0 comments

Comments

@in-seo
Copy link
Member

in-seo commented Sep 24, 2022

스프링의 탄생

  • EJB(Enterprise Java Beans) : 자바의 표준 기술 ( Spring + JSP ) 합친 느낌
    • 비싼 가격 및 구현이 어렵고, 속도가 느린 단점을 가짐.
  • **하이버네이트**(Hibernate)
    • JPA의 새로운 표준 정의
    • EJB **엔티티빈** 기술을 대체
  • *EJB **엔티티빈******하이버네이트***JPA

스프링 역사

  • EJB의 문제점 지적
  • BeanFactory, ApplicationContext, POJO, **제어의 역전**, **의존관계 주입**
  • 겨울을 넘어 새로운 시작이라는 뜻으로 지음.

스프링이란?

  • 스프링 프레임워크, 스프링 부트데이터, 시큐리티, 배치 등 많은 기술을 지원
  • 핵심 기술 : **스프링 DI 컨테이너**, AOP, **이벤트**, **기타**
  • 웹 기술: **스프링 MVC**, **스프링 WebFlux**
  • 데이터 접근 기술 : **트랜잭션**, JDBC, ORM **지원**, XML **지원**
  • 기술 통합 : **캐시**, **이메일**, **원격접근**, **스케쥴링**
  • 테스트 : 스프링 기반 테스트 지원

스프링 부트

  • 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용
    • Tomcat 같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 됨
    • 손쉬운 빌드 구성을 위한 **starter 종속성** 제공
    • 스프링과 3rd part(외부) 라이브러리 자동 구성
    • 관례에 의한 간결한 설정

스프링의 진짜 핵심

  • 스프링은 자바 언어 기반의 프레임워크
  • 자바 언어의 가장 큰 특징 - 객체 지향 언어
  • 스프링은 객체 지향 언어가 가진 강력한 특징을 살려내는 프레임워크
  • 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크

다형성

  • 자동차가 변경되도 운전자에게는 영향이 없다.
  • 이는 자동차 인터페이스에 따라 제작했기 때문이다.
  • 클라이언트는 자동차의 내부구조를 알 필요가 없다.
    • 자동차 역할과 자동차 구현을 분리
  • 다형성을 실세계 비유
    • 운전자 - 자동차
    • 공연 무대
    • 키보드, 마우스, 세상의 표준 인터페이스들
    • 정렬 알고리즘
    • 할인 정책 로직
  • 역할과 구현을 분리
  • 역할구현으로 구분하면 세상이 단순해지고, 유연해지며 변경도 편리해진다.
    • 장점
    • 클라이언트는 대상의 역할만 알면 된다.
    • 클라이언트는 구현 대상의 내부 구조를 몰라도 된다.
    • 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향을 받지 않는다.
    • 클라이언트는 구현 대상 자체를 변경해도 영향을 받지 않는다.
  • 자바 언어의 다형성을 활용
    • 역할 = 인터페이스
    • 구현 = 인터페이스를 구현한 클래스, 구현 객체
    • 객체를 설계할 때 역할구현을 명확히 분리
    • 객체 설계시 역할을 먼저 부여하고, 그 역할을 수행하는 구현 객체 만들기
  • 오버라이딩
    • 오버라이딩 된 메서드가 실행
    • 다형성으로 인터페이스를 구현한 객체를 실행 시점에 유연하게 변경 할 수 있다.
    • 물론 클래스 상속 관계도 다형성, 오버라이딩 적용가능
  • 다형성의 본질
    • 클라이언트를 변경하지 않고, 서버를 구현 기능을 유연하게 변경할 수 있어야 함.
  • 역할과 구현을 분리 한계
    • 역할 자체가 변하면, 클라이언트, 서버 모두에 큰 변경이 발생한다.
    • 인터페이스를 안정적으로 잘 설계하는 것이 중요.
  • 스프링과 객체지향
    • 스프링은 다형성을 극대화해서 이용할 수 있게 도와준다.
    • 스프링에서 이야기하는 **제어의 역전(IoC)**, **의존관계 주입**(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다.
    • 스프링을 사용하면 편리하게 변경할 수 있다.

SOLID

  • 클린 코드로 유명한 로버트 마틴이 좋은 객체 지향 설계의 5가지 원칙을 정리
  • SRP(Single responsibility principle) : 단일 책임 원칙
    • 한 클래스는 하나의 책임만 가져야 한다.
    • 하나의 책임이라는 것은 모호하다.
      • 수 있고, 작을 수 있다
      • 문맥과 상황에 따라 다르다.
    • 중요한 기준은 변경이다. 변경이 있을 때 파급 효과가 적으면 단일 책임 원칙을 잘 따른 것
  • ☆ OCP(Open/closed principle) : 개방 - 폐쇄 원칙
    • 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 한다.
    • 인터페이스는 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현
    • OPC 개방-폐쇄 원칙 문제점
      • 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다.
      • 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정자가 필요하다.
  • LSP(Liskov substitution principle) : 리스코프 치환 원칙
    • 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
  • ISP(Interface segregation principle) : 인터페이스 분리 원칙
    • 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
    • **자동차** 인터페이스 → **운전**, **정비** 인터페이스로 분리
    • **사용자** 클라이언트 → **운전자**, **정비사** 클라이언트로 분리
    • 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않는다.
    • 인터페이스가 명확해지고, 대체 가능성이 높아진다.
  • ☆ DIP(Dependency inversion principle) : 의존관계 역전 원칙
    • 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻.

스프링의 객체 지향

  • 스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원
    • DI(Dependecy Injection) : 의존관계, 의존성 주입
    • DI **컨테이너 제공**
  • 클라이언트 코드의 변경 없이 기능 확장
  • 쉽게 부품을 교체하듯이 개발

IoC(Inversion of Control) : 제어의 역전

  • 기존 프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고, 실행했다. 한마디로 구현 객체가 프로그램의 제어 흐름을 스스로 조종했다.
  • 반면 AppConfig가 등장한 이우에 구현 객체는 자신의 로직을 실행하는 역할만 담당한다. 프로그램의 제어흐름은 Appconfig가 가져간다.
  • 이렇듯 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 **외부에서 관리하는 것을 제어의 역전(IoC)**이라 한다.
  • 프레임워크 vs 라이브러리
    • 프레임워크가 내가 작성한 코드를 제어하고, 대신 실행하면 그것은 프레임워크가 맞다
    • 반면에 내가 작성한 코드가 직접 제어의 흐름을 담당한다면 그것은 프레임워크가 아니라 라이브러리이다.

DI(Dependency Injection) : 의존관계 주입

  • 의존관계는 ‘정적인 클래스 의존관계와, 실행 시점에 결정되는 동적인 객체 의존 관계’ 둘을 분리해서 생각해야한다.
  • ‘정적인 클래스 의존관계’
    • 클래스가 사용한는 import 코드만 보고 의존 관계를 파악.
    • 정적인 의존관계는 애플리케이션을 실행하지 않아도 분석할 수 있다.
  • ‘동적인 객체 인스턴스 의존 관계’
    • 애플리케이션 실행 시점에 실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계다.
    • 애플리케이션 **‘실행 시점(런타임)’**에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결 되는 것을 의존관계 주입이라 한다.
    • 객체 인스턴스를 생성하고 그 참조값을 전달해서 연결된다.
    • 의존관계 주입을 사용하면 클라이언트 코드를 변경하지 않고, 클라이언트가 호출하는 대상의 타입 인스턴스를 변경할 수 있다.
    • 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경할 수 있다.

IoC 컨테이너, DI 컨테이너

  • 객체를 생성하고 관리하면서 의존관계를 연결해주는 것을 **IoC 컨테이너** 또는 **DI 컨테이너**라 한다.
  • 의존관계 주입에 초점을 맞추어 최근에는 주로 **DI 컨테이너**라 한다.
  • 또는, 어셈블러, 오브젝트 팩토리 등으로 불리기도 한다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant