스프링과 객체지향프로그래밍


스프링이란?

  • 자바 언어 기반의 프레임워크
  • 스프링 프레임워크 + 스프링 부트
      • 스프링 데이터, 스프링 시큐리티, 스프링 세션 등
    • 핵심 기술
      • 스프링 DI 컨테이너, AOP, 이벤트, 기타
    • 웹 기술
      • 스프링 MVC, 스프링 WebFlux
    • 데이터 접근 기술
      • JDBC, ORM, 트랜잭션
    • 테스트
      • 스프링 기반 테스트 지원
  • 스프링 부트?
    • 스프링을 편리하게 사용할 수 있도록 지원, 단독으로 실행 가능하도록
    • Tomcat 같은 웹 서버 내장
    • 외부 라이브러리, 버전 호환성을 자동으로 관리해줌
  • 자바 언어의 객체 지향적 특징을 살릴 수 있도록 만든 프레임워크
    • 즉, 좋은 객체 지향 애플리케이션을 만들 수 있게 해줌

객체 지향의 특징?

  • 추상화, 캡슐화, 상속, 다형성
  • 프로그램을 독립된 단위(객체)들의 모임으로 보고, 객체들 간의 메시지 교환, 데이터 처리로 프로그램을 구성하는 것
  • 프로그램을 유연하고 변경이 용이하도록 만듬
    • 이건 다형성의 특징을 말하는 것
    • 역할(인터페이스)과 구현(구현체)을 구분하여 사용자는 인터페이스에만 의존을 하도록 함
    • 따라서 구현체는 유연하게 변경되어도 사용자는 무관
      • 사용자는 대상의 역할(인터페이스)만 알면 됨
      • 클라이언트는 구현 대상(구현체)의 내부 구조를 몰라도 되고, 내부 구조가 변경되더라도 영향을 받지 않음
      • 구현 대상(구현체) 자체를 변경해도 영향을 받지 않아야 함
    public interface MemberRepository {}

    public class MemberMemberRepository implements MemberRepository {}
    public class JdbcMemberRepository implements MemberRepository {}
    public class MemberService {
        //private MemberRepository memberRepository = new MemoryMemberRepository();
        private MemberRepository memberRepository = new JdbcMemberRepository();
    }
  • 즉, 다형성의 본질은?
    • 클라이언트를 변경하지 않고, 서버의 구현 기능을 유연하게 변경할 수 있음
  • 다형성의 한계는?
    • 역할(인터페이스) 자체가 변경되면 구현(구현체)도 모두 수정되어야 함

스프링과 객체 지향

  • 객체 지향의 다형성이 가장 중요하고, 스프링은 이 다형성을 극대화해서 이용할 수 있도록 해줌
  • 제어역전(IoC), 의존관계 주입(DI) 모두 다형성을 활용한 것

객체 지향 설계의 5원칙

  • SOLID
    • SRP : 단일 책임 원칙 (Single Responsibilty Principle)
      • 한 클래스는 하나의 책임만을 가짐
      • 변경이 있을 때 파급 효과가 적어야 한다는 뜻
    • OCP : 개방-폐쇄 원칙 (Open/Closed Principle), 가장 중요
      • 확장에는 열려있고, 변경에는 닫혀 있어야 한다는 것 -> 다형성, 위의 코드 참고
      • 구현체를 변경하려면 결국 클라이언트(MemberService)를 수정해야 함 -> OCP 원칙 위배
      • 객체를 생성하고 연관관계를 맺어주는 설정자가 필요 -> 스프링의 DI, IoC로 해결
    • LSP : 리스코프 치환 원칙 (Liskov Substitution Principle)
      • 프로그램의 객체는 정확성을 깨지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 함
      • 즉, 다형성에서 하위 클래스는 인터페이스의 규약을 다 지켜야 한다는 것
    • ISP : 인터페이스 분리 원칙 (Interface Segregation Principle)
      • 특정 클라이언트 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다
      • e.g. 자동차 인터페이스 -> 운전 인터페이스 + 정비 인터페이스
      • 인터페이스가 명확해지고, 대체 가능성이 높아짐
    • DIP : 의존관계 역전 원칙 (Dependency Inversion Principle)
      • 추상화에 의존하고, 구체화에 의존해선 안된다
      • 즉, 구현 클래스에 의존하지 않고 인터페이스에 의존해야 한다
      • 위의 예제 코드에서 MemberService는 DIP 원칙을 위배함
        • 클라이언트가 구현 클래스를 직접 선택 -> DIP 위반
        • MemberRepository m = new MemoryMemberRepository();
          

정리

  • 객체 지향의 핵심은 다형성
  • 다형성 만으로는 OCP, DIP 원칙을 지킬 수 없음
  • 즉, 클라이언트 코드와 구현 객체를 완전히 분리가 불가능
  • 이걸 해결해주는게 스프링 프레임워크

객체 지향 설계와 스프링

  • 스프링에서 다형성 + OCP, DIP를 가능하게 지원하는 방법?
    • DI(Dependency Injection) : 의존관계, 의존성 주입
    • DI 컨테이너 제공
  • 클라이언트 코드의 변경 없이 기능 확장이 가능하고, 쉽게 부품 교체하듯이 개발이 가능함





© 2020.02. by blupine