[Spring] 스프링 핵심 원리 - 기본편 (1) - 객체 지향 설계와 스프링



요즘 잘 모르고 개발하고 있나 라는 생각이 점점 들어서 강의를 들어보기로 했다.
좀 더 실무에 맞게 스프링을 어떻게 사용하는지 이해할 수 있었으면…


섹션 1. 객체 지향 설계와 스프링


(1) 이야기 - 자바 진영의 추운 겨울과 스프링의 탄생

자바 ORM, JPA

  • EJB -> (POJO) -> 스프링
  • EJB 엔티티빈 -> 하이버네이트 -> JPA(자바표준)


스프링 역사

  • Rod Johnson의 책에 있는 예제 코드를 바탕으로 만들어짐

스프링을 왜 이렇게 많이 쓸까?에 대해서 실습을 통해 알아가게 될 것이다…


(2) 스프링이란?

: 여러가지 기술들의 모음
https://spring.io/projects

  • 스프링 프레임워크 : 가장 중요함. 핵심기술!
  • 스프링 부트 : 스프링을 편리하게 사용할 수 있도록 지원


스프링 프레임워크 특징

  • DI 컨테이너, AOP, 이벤트 등등…. 스프링 라이브러리를 이용해서 핵심 기술 제공


스프링 부트 특징

  • 웹서버를 내장
  • 쉬운 빌드
  • 라이브러리 자동 구성
  • 편한 설정


스프링의 핵심 개념/컨셉

  • 자바 언어 기반 프레임워크 -> 객체 지향 언어
    -> 스프링은 좋은 객체 지향 애플리케이션을 개발할 수 있게 도와주는 프레임워크 (그게 DI 컨테이너)


좋은 객체 지향이 뭔지 알아야 스프링의 본질을 더 이해하기 쉬울 것이다.


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

객체 지향 프로그래밍?

  • 객체들의 모임, 객체끼리 협력한다.
  • 유연&변경 용이 => 다형성


다형성

  • 클라이언트에 영향을 주지않고, 새로운 기능 제공 가능
  • 클라이언트가 내부 구조를 몰라도, 역할과 구현이 정해져있으면 대체 가능
  • 예시
    • 운전자-자동차
    • 공연 무대

-> 역할(인터페이스)과 구현(구현 클래스, 객체)을 분리해야, 유연하고 변경이 용이해진다.

결론 : 인터페이스를 안정적으로 설계하는 것이 중요하다 ! (변화가 없도록~)


스프링과 객체 지향

  • 객체 지향은 다형성이 정말 중요
  • 제어의 역전(IoC), 의존관계 주입(DI) -> 다형성을 활용하여 역할과 구현을 편리하게 다룰 수 있게 지원하는 거임

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

SRP 단일 책임 원칙

  • 1 클래스 1 원칙
  • 하나의 책임은 모호하다
    • 중요한 기준은 변경이다.
    • 한 번 변경할 때, 하나의 클래스나 지점을 고치면 잘 되어있는거라고 볼 수 있음


OCP 개방-폐쇄 원칙

  • 확장은 열려있으나, 변경은 닫혀있어야 한다.
  • 다형성을 활용해보자~
  • 문제점
    • 다형성에서 MemberService 클라이언트가 구현 클래스를 직접 선택한다 -> OCP 실패
      => 별도로 조립해주는 설정자가 필요하다.
      이걸 스프링의 컨테이너가 해줄 것이다.


LSP 리스코프 치환 원칙

  • 기능적으로 인터페이스 규약을 지켜야 한다. (ex. 자동차의 엑셀은 앞으로 가야한다.)


ISP 인터페이스 분리 원칙

  • 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.
  • 예시
    • 자동차 인터페이스 -> 운전 / 정비 인터페이스
    • 사용자 클라이언트 -> 운전자 / 정비사 클라이언트로 분리
  • 인터페이스가 명확해지고, 대체 가능성이 넓어진다.


DIP 의존관계 역전 원칙

  • 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”
  • 클라이언트가 인터페이스를 바라봐야한다. (ex. 운전자는 자동차에 대해서만 알면 된다)
  • DIP 위반 코드
    MemberRepository memberRepository = new MemoryMemberRepository();
    


정리

  • 다형성만으로는 OCP와 DIP를 지킬 수 없다.
  • 쉽게 갈아끼울 수 있어야 한다는 것이 핵심.
  • OCP랑 DIP가 중요

(5) 객체 지향 설계와 스프링

스프링없이 OCP,DIP 원칙을 지키며 개발하기

  • 너무 할일이 많아서, 프레임워크로 만드는 것이 더 낫다.
    -> DI 컨테이너의 필요성을 알게 될 것이다.

정리

  • 모든 설계에 역할과 구현을 분리하자
  • 이상적으로는 모든 설계에 인터페이스를 구현하는 것이 좋음.
  • 인터페이스를 만드는 것의 장점
    • 구체적으로 어떻게 구현할지 정해지지 않아도, 일단 개발을 시작할 수 있다.
  • 인터페이스를 만드는 것의 단점
    • 추상화라는 비용이 발생한다.
    • 코드를 읽을 때, 구현 클래스가 무엇인지 알 수 없다.

=> 확장할 가능성을 고려해서 선택하는게 낫다.

다른 글