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

HJ·2022년 7월 28일
0
post-thumbnail

김영한 님의 스프링 핵심 원리 - 기본편 강의를 보고 작성한 내용입니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard


1. 용어

  • JPA : 자바 표준 인터페이스 / ORM 기술

  • Hibernate : JPA 구현체

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

  • 스프링 DI 컨테이너 기술 : 스프링 빈을 관리




2. 스프링 프레임워크

  • 핵심 기술 : 스프링 DI 컨테이너

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

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

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

  • 테스트: 스프링 기반 테스트 지원

  • 언어: 코틀린, 그루비

  • 최근에는 스프링 부트를 통해서 스프링 프레임워크의 기술들을 편리하게 사용




3. 스프링부트

  • 스프링을 편리하게 사용할 수 있도록 지원

    • 여러 스프링 기술들을 편하게 사용할 수 있도록 도와줌

    • 스프링 프레임워크를 편리하게 사용할 수 있도록 하는 기능을 지원

    • 스프링 프레임워크와 별도가 아니라 스프링 프레임워크를 사용하고 필요 시 다른 것들을 가져와서 사용

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

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

    • 빌드하고 서버를 띄우는 것까지 한 번에 가능
  • 손쉬운 빌드 구성을 위한 starter 종속성 제공

    • 한 라이브러리를 가져오면 starter가 나머지 라이브러리까지 가져와줌
  • 스프링과 외부 라이브러리 자동 구성

    • 스프링이 호환되는 외부 라이브러리의 버전에 맞는지 검사하기 때문에 버전을 신경쓰지 않고 다운로드 가능 ( 라이브러리 버전 최적화 )



4. 스프링의 핵심

  • 스프링은 자바 언어 기반의 프레임워크이고 자바 언어의 가장 큰 특징은 객체 지향 언어라는 점이다

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

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




5. 객체 지향 프로그래밍

  • 컴퓨터 프로그램 = 객체들의 모임

  • 객체 지향 특징

    • 추상화
    • 캡슐화
    • 상속
    • 다형성
  • 각각의 객체는 메세지를 주고 받고, 데이터를 처리할 수 있다

    • 객체들은 혼자 있지 않고 서로 협력 관계를 가진다

    • ex> 클라이언트 <--> 서버 / 서버 <--> 서버

  • 객체 지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 만든다

    • 부품을 갈아 끼우듯이 컴포넌트를 쉽고 유연하게 변경할 수 있다
      ==> 다형성



6. 다형성

  • 역할 (인터페이스)과 구현 (인터페이스를 구현할 클래스 혹은 객체)이 있다고 가정했을 때

    • ex> 운전자는 자동차가 바뀌어도 운전하는 방식은 변하지 않기 때문에 자동차의 역할(인터페이스)만 알면 구현(객체)가 변경되어도 문제가 없다

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

    • 클라이언트는 구현 대상 자체 (구현된 객체) 혹은 구현 대상의 내부구조를 변경해도 영향을 받지 않는다

      • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다
      • 변경이 편리해진다
  • 객체를 설계할 때 역할과 구현을 명확히 분리하여 역할(인터페이스)을 먼저 부여하고, 구현(그 역할을 수행하는 객체)을 만든다
  • 참고

    • 인터페이스가 의존관계가 있을 때, 구현한 객체를 할당 가능

    • 할당된 객체의 오버라이딩 된 메소드가 실행된다




7. 스프링과 다형성

  • 스프링은 다형성을 극대화해서 이용할 수 있게 도와준다

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

  • 스프링은 구현(객체)을 편리하게 변경할 수 있다




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

8-1. SRP

  • 단일 책임 원칙( single responsibility principle )

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

    • 책임에 대한 범위를 잘 정해야 한다
  • 중요한 기준은 변경!

  • 변경이 있을 때 파급 효과가 적으면 ( 다른 코드를 변경하지 않아도 된다면 ) 단일 책임 원칙을 잘 따른 것


8-2. OCP

  • 개방-폐쇄 원칙 ( Open/closed principle )

  • 확장에는 열려 있으나, 변경에는 닫혀 있어야 한다

  • 다형성을 활용

  • 확장을 하려면 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현하면 된다


8-3. LSP

  • 리스코프 치환 원칙 ( Liskov substitution principle )

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

  • 인스턴스를 변경해도 기능이 달라지지 않아야 한다

  • 즉, 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다

  • ex> 자동차에서 엑셀은 앞으로 가는 것인데 뒤로 가도록 구현하면 LSP를 위반한 것임


8-4. ISP

  • 인터페이스 분리 원칙 ( Interface segregation principle )

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

  • 하나의 인터페이스를 여러 개의 인터페이스로 분리

  • 분리하면 인터페이스가 명확해지고, 대체 가능성이 높아진다

  • 인터페이스를 분리하면 클라이언트도 분리 가능

    • 이 때, 한 인터페이스가 변경되어도 클라이언트 역시 분리되었기 때문에 전체 클라이언트가 영향을 받진 않는다
  • 예시>

    • 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리

    • 사용자 클라이언트 -> 운전자 클라이언트, 정비사 클라이언트로 분리

    • 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않음

    • 사용자 클라이언트 전체를 변경하지 않아도 된다


8-5. DIP

  • 의존관계 역전 원칙 ( Dependency inversion principle )

  • 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다” 의존성 주입은 이 원칙을 따르는 방법 중 하나다

  • 구현 클래스에 의존하지 말고, 인터페이스에 의존하라는 뜻

  • 구현체에 의존하면 변경이 매우 어려워진다

  • 클라이언트가 인터페이스에 의존해야 유연하게 구현체를 변경할 수 있다




9. 객체 지향 원칙 위반 상황

9-1. DIP 위반

public class MemberService {

    private MemberRepository m = new MemoryMemberRepository();
}
  • MemberService는 인터페이스에 의존하지만, 구현 클래스도
    동시에 의존한다

  • 즉, 클라이언트가 구현 클래스를 직접 선택하고 있다


9-2. OCP 원칙 위반

public class MemberService {

    private MemberRepository m = new MemoryMemberRepository(); //기존 코드
    private MemberRepository m = new JdbcMemberRepository(); //변경 코드
}
  • 구현 객체를 변경하려면 클라이언트(MemverService) 코드를 변경해야함

  • 다형성을 사용했지만, OCP 원칙을 지킬 수 없다


9-3. OCP 원칙 위반 해결방안

  • 객체를 생성하고, 연관 관계를 맺어주는 별도의 조립, 설정자가 필요

  • 이 기능은 스프링 (스프링 컨테이너)이 해준다

  • OCP 원칙을 지키기 위해 DI, IoC Container가 필요


9-4. 정리

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

  • 다형성만으로는 구현 객체를 변경할 때 클라이언트 코드도 함께 변경되기 때문에 OCP, DIP 원칙을 지킬 수 없다

  • 추가적인 기술( IoC, DI )이 필요




10. 객체 지향 원리와 스프링

  • 스프링은 DI, DI Container로 다형성 + OCP, DIP가 지켜지도록 지원

  • 즉, 클라이언트 코드의 변경 없이 기능을 확장할 수 있고, 쉽게 부품을 교체하듯이 개발할 수 있다




11. 강의 내용 정리

  • 모든 설계에 역할(인터페이스)과 구현(객체)를 분리

  • 객체는 인터페이스에만 의존해야한다

  • 객체는 언제든지 유연하게 변경할 수 있도록 만드는 것이 좋은 객체 지향 설계이다

0개의 댓글