[Spring] 🌱스프링 핵심 원리 강의 메모

2022. 6. 10. 00:45TIL💡/Java

이전 인턴을 수행하면서 객체지향언어인 C#dmf 익히고, 객체 지향 프로그래밍에 대한 이론적인 습득도 하였으나 정작 실무에서 제대로 써먹지는 못했었다.

 

그래서 아쉬움 마음도 달래고, 배움을 멈추지 않기 위해 오히려 Spring을 통해 객체지향을 본격적으로 배우고 싶은 마음에 해당 강의를 수강하기 시작하기로 하였다.

 

다행스럽게도 학부 시절 전공 시간에 소*민 교수님의 명강인 Java를 들어둔 덕분에 어렵지 않게 입문했다.

 

스프링이란?

필수

스프링 프레임워크, 스프링 부트

 

선택

스프링 데이터, 세션, 시큐리티, Rest Docs, 배치, 클라우드

 

 

스프링 리액티브 프로그래밍 : Java에서도 Non-Blocking 기술 활용 가능

 

🌱 스프링 프레임워크

- 핵심 기술: 스프링 DI 컨테이너, AOP, 이벤트, 기타...

- 웹 기술: 스프링 MVC, 스프링 WebFlux

- 데이터 접근 기술: 트랜잭션, JDBC, ORM 지원, XML 지원

- 기술 통합: 캐시, 이메일, 원격 접근, 스케줄링

- 테스트

- 언어: 코틀린, 그루비

 

🌱 스프링부트

- 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용

- 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성

- Tomcat 같은 웹서버를 내장해서 별도의 웹 서버를 설치하지 않아도 됨

- 손쉬운 빌드 구성을 위한 starter 종속성 제공

- 스프링과 외부 라이브러리 자동 구성

- 메트릭, 상태 확인, 외부 구성 같은 프로덕션 준비 기능 제공

- 관례에 의한 간결한 설정

 

스프링의 핵심 개념

- 스프링은 자바 언어 기반의 프레임워크

- 자바 언어의 가장 큰 특징 - 객제 지향 언어 사용

- 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있도록 한다.

 

(그러면) 좋은 객체 지향 프로그래밍이란?

프로그램을 객체들의 모임으로 만들어서, 객체들이 협력하여 처리하도록 한다.

레고 블럭을 조립하듯이, 부품을 갈아 끼우듯이 쉽고 유연하게 변경할 수 있도록 한다.

 

이는 바로 다형성(Polymorphism)이다.

실세계와 객체 지향을 일대일로 매칭하는 것은 좋지 않고, 비유 정도로 적당하게 해보자

역할(인터페이스)과 구현으로 세상을 구분해보자.

 

연극 배우가 아파도 연극은 진행되어야 한다.

따라서 연극 역할과 연극 배우는 분리되어서, 다른 배우가 해당 역할을 수행할 수 있도록 해야 한다.

 

역할과 구현을 분리

- 역할과 구현으로 구분하면 세상이 단순해지고, 유연해지며 변경도 편리해진다.

- 장점

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

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

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

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

 

다형성의 본질

🌱 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경할 수 있다.

🌱 다형성의 본질을 이해하려면 협력이라는 객체 사이의 관계에서 시작해야 한다.

🌱 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.

 

한계

만약 인터페이스가 변경된다면? 모두 변경해야 한다..

따라서 인터페이스를 안정적으로 잘 설계하는 것이 중요하다.

 

좋은 객체 지향 설계의 5가지 원칙(SOLID)

가끔 면접에 나올 수 있다..

🌱 SRP(Single Responsibility Principle)

- 한 클래스는 하나의 책임만 가져야 한다.

- 하나의 책임이라는 것은 모호하다.

- 중요한 기준은 변경이다. 변경이 있을 때 파급효과가 적으면 SRP를 잘 따른 것

 

🌱 OCP(Open-Closed Principle)

- 소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀있어야 한다.

- 다형성을 활용해보자. 앞서 말한 인터페이스를 사용하면 적용된다.

MemberRepository 구현체를 교체하기만 하면 된다.

 

🌱 LSP(Liskov Substitution Principle)

- 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.

- 단순히 컴파일에 성공하는 것을 넘어서 상위 규약을 지키자.

 

🌱 ISP(Interface Segregation Principle)

- 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.

 

🌱 DIP(Dependency Inversion Priciple)

- 클라이언트 코드가 구현을 바라보지 말고, 인터페이스를 바라보도록 해야 한다.(추상화에 의존해야지, 구체화에 의존하면 안된다.)

- 구현을 몰라도 굴러갈 수 있도록 한다.

 

정리

- 객체 지향의 핵심은 다형성

- 다형성만으로는 쉽게 부품을 갈아 끼우듯이 개발할 수 없다.

- 다형성만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경된다.

- 다형성만으로는 OCP, DIP를 지킬 수가 없다.

- 뭔가 더 필요하다.

 


스프링의 역할

스프링은 다음 기술로 다형성 + OCP, DIP를 가능하게 지원한다.

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

- DI 컨테이너 제공

 

실무에서 인터페이스를 활용하면?

구현을 최대한 미룰 수 있다는 장점이 있다.

어떤 데이터베이스를 쓸 지도 나중에 정해도 된다.

대신 인터페이스로 추상화라는 비용이 발생한다.

기능을 확장할 가능성이 없다면, 구체 클래스를 직접 사용하고 향후 꼭 필요할 때 리팩터링해서 인터페이스를 도입하는 것도 방법이다.