프로그래밍공부(Programming Study)/스프링(Spring Framework)

2022.04.20 스프링 기본원리 공부

Chaany 2022. 4. 21.
728x90
스프링 프레임워크

 

1. EJB (Enterprise Java Beans) -> JAVA, JSP, Servlet 종합 -> 정파의 기술
- 단점 : 비용이 많이 들고, 어렵고 복잡하고 느림

2. POJO(Plain Old Java Object) - 오래된 방식의 자바방식으로 돌아가자!

3. 스프링 탄생(Rod Johnson)

- EJB 컨테이너 대체

4. 하이버네이트(Gavin king)

- EJB 엔티티빈 대체

- JPA(Java Persistance API) 새로운 표준 정의

 

스프링이란?
 
스프링의 핵심 개념,컨셉

- 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크

좋은 객체 지향 프로그래밍이란?
 
객체지향프로그래밍 - 유연하고 변경이 용이하게 개발할 수 있다

-> 다형성(polymorphism) ex)자동차, 공연(로미오와줄리엣), 키보드, 마우스, 표준인터페이스, 정렬 알고리즘, 할인 정책 로직 등

다형성 + SOLID -> 좋은 프로그래밍

역할 - 인터페이스

기능 - 구현체

클라이언트에 영향 주지 않고 계속 개발할 수 있다.

 

다형성의 본질

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

한계

- 역할(인터페이스) 자체가 변하면 클라이언트, 서버 모두에 큰 변경이 발생함

- 인터페이스를 매우 잘 설계해야 함

결국 스프링의 IoC(제어의 역전), 의존관계 주입(DI)는 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한 것

 

좋은 객체 지향 설계의 5가지 원칙(SOLID)
 
SRP(Single Responsibility Principle) 단일책임원칙

- 중요한 기준은 변경 - 파급효과가 적으면 단일 책임 원칙을 잘 따른 것 ex) UI변경, 객체의 생성과 사용 분리

OCP(Open/Closed Principle) 개방-폐쇄원칙

-가장 중요한 원칙

-확장에는 열려 있으나 변경에는 닫혀 있어야 함

- 다형성을 활용해보자

문제점

- 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다.

- 분명 다형성을 사용했지만 OCP원칙을 지킬 수 없다.

-> 해결법

- 별도의 조립, 설정자가 필요함

-> 이것이 스프링 컨테이너의 역할

 

LSP(Liskov Substitution Principle) 리스코프 치환 원칙

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

- 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것

- 인터페이스를 구현한 구현체를 믿고 사용하기 위함

 

ISP(Interface Segregation Principle) 인터페이스 분리 원칙

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

- 인터페이스가 명확해지고, 대체 가능성이 높아짐

 

DIP (Dependency Inversion Principle) 의존관계 역전 원칙

- 추상화에 의존해야지, 구체화에 의존하면 안된다.

- 역할에 의존하게 해야 한다.

- 구현체에 의존하게 되면 변경이 아주 어려워 진다.

ex) 운전자는 자동차 역할에 대해서 알아야지 테슬라의 기능에 대해서 알면 안된다.

 

정리

- 객체 지향의 핵심 원리는 다형성

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

- 뭔가 더 필요하다 -> 

 

 

객체 지향 설계와 스프링
 
추상화가 되면 코드를 한 번 더 열려 봐야 함 -> 비용이 발생

장점이 단점을 넘어설 때 선택하자.

때에 따라서 리팩토링해서 인터페이스랑 클래스를 분리해도 상관 없음

 

(책 추천)

객체지향 책 : 객체지향의 사실과 오해

스프링 책 : 토비의 스프링

JPA 책 : 자바 ORM 표준 JPA 프로그래밍 

 

스프링 핵심 원리 이해1 - 예제 만들기
 
설계 단계
 
- 도메인 협력 관계 -> 기획자도 볼 수 있음

- 클래스 다이어그램 -> 개발자 설계

- 객체 다이어그램 -> 인스턴스 끼리의 참조 관계 설계

 

구현 단계

 

- 역할과 구현체는 다른 디렉토리로 쓰는게 좋음
 
- 실무에서는 동시성 이슈로 concurrentHashMap 써야함
 
- primitive type = null 안됨 -> 초기화 해야함(자동초기화 되긴 함)

- 구현체가 딱 하나 일 경우 Impl로 많이 씀

- 클래스 - 정적 / 객체 - 동적 다이어그램

- test 디렉토리는 배포할 때 제외하고 배포됨

- given - when - then 구조로 테스트 코드 짜기

- 실무자들의 60%가 업무시간에 테스트코드 개발중일 정도로 테스트 코드 작성 매우 중요함)

- 객체 -> 동적 다이어그램으로 실제 new해서 쓸 때를 가정하고 설계

애자일 소프트웨어 개발 선언 참고

(AppConfig 구현)

 
- AppConfig : 구현 객체 생성, 생성자를 통해서 주입(연결)하는 설정 클래스

- 생성자주입 : 생성자를 통해서 객체를 구현

의존관계에 대한 고민은 외부에 맡기고 실행에만 집중

관심사의 분리 : 객체 생성하고 연결하는 역할과 실행하는 역할이 명확히 분리됨

DI : 의존관계 주입, 의존성 주입

 
 
IoC, DI, 그리고 컨테이너
 

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

= 프로그램에 대한 제어 흐름은 AppConfig가 가져가버림

- 프로그램의 제어흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것

- 프레임워크 : 프레임워크는 (특정 라이프사이클 속에서)내가 작성한 코드를 제어하고 대신 실행한다.

- 라이브러리 : 내가 작성한 코드가 직접 제어의 흐름을 담당한다면 라이브러리 

 

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

- 정적인 클래스의 의존 관계와, 실행 시점에 결정되는 동적인 객체(인스턴스)의존 관계 둘을 분리해서 생각해야 한다.

- 정적인 의존관계는 애플리케이션을 실행하지 않아도 분석 가능 (Show diagram) 다이어그램에서 화살표방향은 의존하고 있는 방향

- 하지만 실제 어떤 객체가 주입될 지는 알 수없음

-> 동적인 객체 인스턴스 의존 관계

: 애플리케이션 실행 시점에  실제 생성된 객체 인스턴스의 참조가 연결된 의존 관계

-실행시점(런타임)에 외부에서 실제 구현 객체를 생성하고 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 연결되는 것을 의존관계 주입이라 함

- 객체인스턴스를 생성하고, 그 참조값을 전달해서 연결

- 정적인 클래스 의존관계를 변경하지 않고(애플리케이션 코드를 전혀 손대지 않고) 동적인 클래스의 의존관계만 쉽게 변경할 수 있다.

 

IoC, DI 컨테이너

- Appconfig와 같이 의존관계를 연결해주는 컨테이너

- 최근에는 DI컨테이너라함(의존관계 주입에 초점)

- 어셈블러, 오브젝트 팩토리라 불리기도 함

728x90

댓글