Home Spring Framework - 객체 지향 설계와 스프링
Post
Cancel

Spring Framework - 객체 지향 설계와 스프링

스프링이란?

  • 여러가지 기술(모듈)들의 집합
    • 스프링 데이터, 스프링 세션, 스프링 시큐리티 등등

Spring Framework

  • 핵심 기술 : 스프링 DI 컨테이너, AOP, 이벤트, 기타
  • 웹 기술 : 스프링 MVC, 스프링 WebFlux
  • 데이터 접근 기술 : 트랜잭션, JDBC, ORM 지원, XML 지원
  • 기술 통합 : 캐시, 이메일, 원격접근, 스케쥴링
  • 테스트 : 스프링 기반 테스트 지원
  • 언어 : 코틀린, 그루비

Spring Boot

  • 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용
  • 단독으로 실행할 수 있는 스프링 어플리케이션 생성
  • 톰캣 같은 웹서버를 내장하여 별도의 웹 서버를 설치하지 않아도 됨
  • 손쉬운 빈드 구설을 위한 스타터 종속석 제공
  • 스프링과 서드파티 외부 라이브러리 자동 구성
  • 메트릭, 상태확인, 외부 구성 같은 프로덕션 준비 기능 제공
  • 관례에 의한 간결한 설정

핵심 개념

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

객체지향 - 다형성의 본질

  • 인터페이스를 구현한 객체 인스턴스를 실행 시점유연하게 변경할 수 있다.
  • 다현성의 본질을 이해하려면 협력이라는 객체사이의 관계에서 시작해야함
  • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있다.

Alt text

객체지향 - 역할과 구현을 분리

  • 실세계의 역할과 구현이라는 편리한 컨셉을 다형성을 통해 객체 세상으로 가져올 수 있음
  • 유연하고, 변경에 용이
  • 확장 가능한 설계
  • 클라이언트에 영향을 주지 않는 변경 가능
  • 인터페이스를 안정적으로 잘 설계하는 것이 중요

객체지향 - SOLID

SRP(Single Responesibility Principle) - 단인 책임 원칙
  • 한 클래스는 하나의 책임만 가진다. 그러나 하나의 책임이라는 것을 모호한 개념
    • 클 수 있고, 작을수 있음
    • 문맥과 상황에 따라 다름
  • 주요 기준은 변경이다. 변경이 있을때 마다 파금효과가 적으면 SRP를 잘 따른것
  • 예) UI 변경, 객체의 생성과 사용을 분리
OCP(Open Closed Principle) - 개방-폐쇠 원칙
  • 소프트웨어의 요소는 확장에는 열려있으나 변경에는 닫혀 있어야 한다
  • 다형성을 활용하여 구현
  • 인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현
  • 구현 객체를 변경하려면 클라이언트 코드를 변경해야 함
    • 다형성을 사용해도 완벽히 OCP 원칙을 지킬수 없음
    • 객체를 생성하고, 연관관계를 맺어주는 별도의 조립, 설정하가 필요함
      • 스프링의 역할
        1
        2
        3
        
         // 인터페이스에 구현체를 할당하는 과정에서 기존 코드의 변결이 필요해짐
         InterfaceA a = new DerivedA();  // 기존코드
         InterfaceA a = new DerivedAA(); // 변경코드
        
LSP(Liskov Substitution Principle) - 리스코프 치환 원칙
  • 프로그램의 객체는 프로그램의 정확설을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀수 있어야 함
  • 다형성에서 하위 클래스는 인터페이스 규약을 다 지켜야 한다는 것
  • 다형성을 지원하기 위한 원칙
  • 단순히 컴파일 성공을 넘어서는 이야기
  • 예) 자동차 인터페이스의 엑셀은 앞으로 가라는 기능. 뒤로 가게 구현하면 LSP 위반.
ISP(Interface Segregation Principle) - 인터페이스 분리 원칙
  • 특정 클라이언트를 위한 인터페이스 여러개가 범용 인터페이스 하나보다 나음
  • 자동차 인터페이스 -> 운전 인터페이스, 정비 인터페이스로 분리
  • 사용자 클라리언트 -> 운전자 클라이언트, 정비사 클라이언트로 분리
  • 분리하면 정비 인터페이스 자체가 변해도 운전자 클라이언트에 영향을 주지 않음
  • 인터페이스가 명확해지고 대체 가능성이 높아짐
DIP(Dependecy Inversion Principle) - 의존관계 역전 원칙
  • 추상화에 의존해야지, 구체화에 의존해선 안됨. 즉 구현 클래스에 의존하지 말고 인터페이스에 의존해야함
  • 객체 세상도 클라이언트가 인터페이스에 의존해야 구현체를 변경할 수 있음
  • 구현체에 의존하게 되면 변경이 어려워짐
  • 인터페이스에 구현체를 할당하는 과정에서 구현 클래스를 의존하게됨
    • 완벽히 DIP 원칙을 지킬수 없음
      1
      2
      3
      
       // 인터페이스에 구현체를 할당하는 과정에서 DerivedAA 라는 구현체가 필요하므로
       // DerivedAA 라는 구현체에 의존하게됨
       InterfaceA a = new DerivedAA();
      
SOLID 정리
  • 객체 지향의 핵심은 다형성
  • 다형성 만으로는 구현 객체를 변경 할때 클라이언트 코드도 함께 변경됨
  • 다형성 만으로는 OCP, DIP를 만족 할수 없음

스프링과 객체지향

  • 다형성이 중요
  • 스프링은 다형성을 극대화 하여 이용할 수 있게 도와준다
  • 스프링에서 이야기 하는 제어의 역전(IoC), 의존관계 주입(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다
  • 스프링은 다음 기술로 다형성 + OCP, DIP를 만족할 수 있게 지원
    • DI(Dependency Injection) : 의존관계, 의존성 주입
    • DI 컨테이너 제공
  • 클라이언트 코드의 변경없이 기능 확장

정리

  • 모든 설계에 영할구현을 분리해야 함
  • 이상적으로는 모든 설계에 인터페이스를 부여해보자
  • 하지만 인터페이스를 도입하면 추상화라는 비용이 발생
    • 런타임에 어떠한 구현 클레스를 사용하고 있는지 확인이 필요
  • 기능을 확장할 필요가 없다면 구현 클래스를 직접 사용하고, 향후 꼭 필요할때 리펙토링을 하여 인터페이스를 도입하는 것도 하나의 방법

참고

  • 스프링 핵심 원리 - 기본편(김영한)
This post is licensed under CC BY 4.0 by the author.