본문 바로가기

공부/Spring

[서적 핵심 정리 - 토비의 스프링 3] Ch1. 오브젝트와 의존 관계

관심사의 분리 (Separation of Concerns)

  • 관심이 같은 것끼리 하나의 객체 또는 친한 객체로 모음
  • 관심이 다른 것은 가능한 따로 떨어져서 서로 영향을 주지 않도록 분리
  • 즉, 객체지향 설계의 기본 원칙인 High Cohesion, Low Coupling과 동일한 의미

리팩토링 (Refactoring)
  • 기존의 코드를 외부의 동작 방식에 변화 없이 내부 구조를 변경해서 재구성하는 작업 또는 기술을 의미

템플릿 메소드 패턴 (Templete Method Pattern)
  • 변하지 않는 기능을 슈퍼 클래스에 정의하고, 확장할 기능을 서브클래스에서 상속하여 정의하게 한다. 확장할 메소드를 템플릿 메소드라고 하며, 아래와 같은 방법으로 정의할 수 있다.
    • 추상 메소드 (abstract method) 
    • 훅 메소드 (hook operation) : 기본적인 연산을 제공하고, 필요할 경우 서브 클래스에서 이를 확장하도록 한다.

팩토리 메소드 패턴 (Factory Method Pattern)
  • 객체의 생성을 담당하는 메소드(팩토리 메소드)를 서브클래스에서 정의하거나 확장하는 패턴 (일종의 템플릿 메소드 패턴으로 볼수 있음)

객체 지향 설계 원칙 (SOLID)
  • 단일 책임 원칙 (The Single Responsibility Principle)
    • 특정 클래스를 변경해야 하는 이유는 오직 하나뿐이여야 함
    • 즉, 클래스는 하나의 목적에 대한 기능을 포함해야 함을 의미
  • 개방 폐쇄 원칙 (Open-Closed Principle)
    • 클래스나 모듈, 함수는 확장에는 열려있어야 하고, 변경에는 닫혀있어야 함
  • 리스코프 치환 법칙 (Liskov Substitution Principle)
    • 서브타입은 언제나 자신의 기반 타입(base type, super type)으로 교체할 수 있어야 함
    • 즉, instanceof 나 다운 캐스트를 사용한 코드가 (가급적) 포함되지 않도록 해야 함 
  • 의존 관계 역전 원칙 (Dependency Inversion Principle)
    • 구체적인 클래스/모듈/함수에 의존하기보다는 추상화된 것이 의존해야 함 
    • 추상화된 클래스/모듈/함수는 구상 클래스/모듈/함수에 의존해서는 안된다.
  • 인터페이스 격리 원칙 (Interface Segregation Principle)
    • 클라이언트는 사용하지 않는 메소드에 대해 의존관계를 맺으면 안됨
    • 사용하는 메소드만 인터페이스로 정의하여 제공받아야 함

높은 응집도(High Cohesion), 낮은 결합도(Low Coupling)
  • 모듈 변경이 일어날 때, 해당 변경이 모듈 내에서 전체적으로에 영향을 미친다면 High Cohesion 원칙을 지키지 못하여 발생하는 문제
  • 모듈 변경이 일어날 때, 해당 변경이 다른 많은 모듈에 영향을 미친다면, Low Coupling을 준수하지 못한 것  

전략 패턴 (Strategy Pattern)
  • 변경이 필요한 알고리즘을 인터페이스를 통해 분리하고, 이 인터페이스를 구현한 구상 클래스를 필요에 따라 바꿔 사용할 수 있도록 하는 디자인 패턴

팩토리 사용과 비교하여 어플리케이션 컨텍스트의 이점
  • 객체 요청자가 팩토리 클래스를 알 필요가 없음. 즉, 연관 관계를 제거할 수 있음
  • 어플리케이션 컨텍스트는 어플리케이션 전체에 대한 종합 IoC를 제공
  • 빈을 검색하는 다양한 방법을 제공

스프링 IoC 용어 정리
  • 빈 (Bean)
    • 스프링이 IoC 방식으로 생성, 제어를 담당하는 객체
    • managed object
  • 빈 팩토리 (Bean Factory)
    • 빈을 등록하고, 생성하고, 조회하여 돌려주는 등의 기능을 담당하는 객체
  • 어플리케이션 컨텍스트 (Application Context)
    • 빈 팩토리를 확장한 IoC 컨테이너 
    • 빈 관리 기능과 스프링의 부가 서비스를 추가로 제공
  • 설정정보/설정 메타 정보 (Configuration metadata)
    • 어플리케이션 컨텍스트 또는 빈 팩토리가 IoC를 적용하기 위한 설정 정보
    • XML 또는 annotation 클래스
  • IoC컨테이너 (IoC Container)
    • IoC 방식으로 빈을 관리하는 객체 (빈 팩토리, 어플리케이션 컨텍스트와 동일하게 쓰이기도 함)

싱글톤 레지스트리 (Singleton Registry)
  • 스프링은 별도 설정을 하지 않으면, 여러 번에 걸처 빈을 요청하더라도 매번 동일한 객체를 돌려줌
    • 요청에 대해 매번 객체를 생성해야 할 경우, 객체가 매번 생성되고 사라지면서 성능상 부하를 일으킬 수 있음
  • 스프링은 평범한 자바 클래스를 싱글톤으로 활용할 수 있게 해줌
  • 여러 쓰레드가 동시에 접근할 수 있으므로, 주의해야 함   
    • 무상태(stateless) 방식 (상태 정보를 내부에 갖지 않도록 <-> 상태 유지 방식(stateful))으로 개발 해야 함
    • 스프링 빈 객체가 가질 수 있는 인스턴스 필드
      • 스프링 빈 : 스프링에서 싱글톤으로 관리하므로, 다른 스프링 빈 클래스가 매개변수로 가질 수 있다.
      • 읽기 전용 값 : static final / final 로 선언된 값

스프링 빈 스코프 (Scope)
  • 빈의 라이프 사이클 범위를 의미
  • 스코프 종류
    • Singleton
      • 스프링 빈의 기본 값
      • 컨테이너 내에 하나의 오브젝트만 만들어지며, 컨테이너가 존재하는 동안 계속 유지
    • Prototype
      • 컨테이너에 빈을 요청할 때마다 매번 새로운 오브젝트 생성
    • Request
      • 웹을 통해 새로운 HTTP Request가 생길 대마다 생성
    • Session
      • 웹의 세션과 유사

싱글톤 패턴의 한계
  • 상속이 불가
    • 생성자가 private로 선언되어 있으므로 상속이 불가능
  • 테스트의 어려움
    • 생성을 내부에서 수행하므로, 파라미터 등으로 테스트 값을 주입하기 힘듬
    • 테스트용 오브젝트로 대체하기 힘듬
  • 서버 환경에서는 싱글톤이 하나만 만들어지는 것을 보장하기 힘듬
    • 다수의 JVM에서 분산되어 설치되는 경우, 여러 개일 수 있음 
  • 싱글톤은 전역 상태
    • 객체 지향에서 권장하지 않는 프로그래밍 모델

의존 관계 주입 (DI, Dependency Injection)
  • 의존성 주입/의존 오브젝트 주입 등으로 번역
  • 의존관계를 런타임시에 연결해주는 작업을 의미
  • 의존 관계 주입의 세 가지 조건
    • 클래스 모델이나 코드에서는 런타임 시점의 의존관계가 드러나지 않음. 따라서 인터페이스에만 의존해야 함
    • 런타임 시점의 의존관계는 컨테이너 팩토리같은 제 3의 존재가 결정
    • 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 주입함으로써 만들어짐
  • 의존 관계 주입은 주입 대상과 주입 받는 대상이 모두 스프링 빈이여야 함

의존 관계 검색 (DL, Dependency Lookup)
  • 객체가 자신의 의존 오브젝트를 능동적으로 검색
  • getBean() 메소드를 사용하여 객체를 검색하여 받아오는 방식
  • 주입 받는 대상이 검색하며, 주입 받는 대상은 스프링 빈일 필요가 없음\



출처: 토비의 스프링 3 (이일민 저), GoF의 디자인 패턴 (에릭 감마 외), Java 프로그래머를 위한 UML (로버트 C. 마틴)