Enum

  • 자바 5 이상에서 제공
  • 숫자 형식으로 정의된 상수를 정의하는 것보다 Enum으로 필요한 값을 정의하는 것이 예외 상황을 피하기 좋음


트랜잭션 (Transaction)

  • 데이터베이스에서 최소 작업 단위 (더 이상 나눌수 없음)
  • 데이터베이스 트랜잭션의 ACID 특성
    • 원자성(Atomicity)
      • 트랜잭션은 더 이상 나눌수 없는 작업 단위
      • 트랜잭션은 모두 실행되거나, 모두 실패해야 함 
    • 일관성 (Consistency)
      • 트랜잭션은 데이터 무결성 조건을 만족해야 함
      • 트랜잭션이 성공하면, 데이터베이스는 언제나 일관성 있는 상태로 유지되어야 함
    • 고립성 (Isolation)
      • 트랜잭션은 다른 트랜잭션과 독립적으로 수행되어야 함 (서로 영향을 주어서는 안됨)
    • 지속성 (Durability)
      • 성공적으로 수행된 트랜잭션에 대해 그 결과가 물리적으로 반영되어야 함
  • 대부분의 데이터베이스는 트랜잭션을 지원하며, 실패한 트랜잭션을 Rollback 하거나 성공한 트랜잭션을 Commit하는 명령을 지원


JTA (Java Transaction API)

  • 다수의 DB 또는 트랜잭션을 지원하는 서비스에 대한 통합 트랜잭션 관리 API
  • XA 프로토콜을 통해 다른 서비스를 제어하고 관리


단일 책임의 원칙 (SRP, Single Responsibility Principle)

  • 하나의 클래스는 하나의 책임을 가져야 함
  • 즉, 하나의 클래스를 변경하기 위한 이유는 하나여야 함


테스트 대역 (Test Double)

  • 테스트를 간편히 수행하기 위해 실제 오브젝트의 기능에만 맞춰 만들어진, 테스트에서 사용할 목적으로 만든 객체를 의미
  • 테스트 스텁 (Test Stub)
    • 테스트 동안에 코드가 정상적으로 수행될 수 있도록 돕는 클래스
    • e.g. DummyMailSender
  • 목 오브젝트 (Mock Object)
    • 테스트동안 테스트 대상 오브젝트와 상호작용하는 오브젝트를 테스트하기위한 테스트 대역


대표적인 잘못된 예외처리

  • 예외 블랙홀
    • try-catch 구문으로 감싼 코드 중, 예외에 대한 어떤 처리도 하지 않는 코드를 지칭
    • 모든 예외는 적절하게 복구되거나, 작업을 중단하고 운영자/개발자에게 통보되어야 함
  • 무의미하고 무책임한 throws
    • 특별한 사유 없이 throws Exception을 붙여 예외를 넘겨버리는 코드
    • 이렇게 처리한 메소드를 사용하는 메소드에서는 Exception에 대해 try-catch하거나, throws Exception으로 넘겨버릴 수 밖에 없음


예외의 종류와 특징
  • Error
    • java.lang.Error 클래스의 서브 클래스
    • VM에서 발생시키고, 애플리케이션에서 해결할 수 없는 에러이므로, 특별한 상황 외에 처리할 필요 없음
    • e.g. OutOfMemoryError, ThreadDeath
  • 체크 예외 (Checked Exception)
    • java.lang.Exception 클래스를 상속한 예외 중 RuntimeException을 제외한 예외
    • 명시적으로 try-catch로 처리하거나, throws로 던지지 않으면 컴파일 에러가 발생
    • e.g. IOException, SQLException
  • RuntimeException/언체크 예외 (Unchecked Exception)
    • java.lang.RuntimeException을 상속한 예외
    • 필요시 개발자가 직접 try-catch나 throws를 통해 처리할 수 있음
    • e.g. NullPointerException, IllegalArgumentException

예외 처리 방법
  • 예외 복구
    • 예외 상황을 파악하고, 문제를 해결하여 정상 상태로 돌려놓는 것
  • 예외 처리 회피
    • 예외 처리를 호출한 쪽으로 던지는 것 (throws/rethrow)
    • 반드시 분명한 의도를 가지고 회피를 해야 함
  • 예외 전환 (Exception Translation)
    • 예외를 다른 예외로 전환하여 throw
    • 두 가지 목적으로 사용 가능
      • 예외의 의미를 명확히 하기 위해 (e.g. SQLException --> DuplicateUserIdException)
      • 예외를 처리하기 쉽게 하기 위해 (e.g. 체크예외-->언체크예외)


스프링의 예외 처리

  • SQLException은 대부분 복구 불가능한 예외
  • 스프링의 JdbcTemplete은 런타임 예외인 DataAccessException으로 SQLException을 포장해서 던져줌
  • 또한, DataAccessException은 다양한 DB에 대한 세분화된 예외를 제공
    • e.g. InvalidResultSetAccessException, DuplicateKeyException, DataIntegrityViolationException, ... 
  • 예외 정보를 좀 더 구체화하여 데이터 로직과 다른 로직을 분리하기 용이하게 하고, 다양한 데이터 접근 기술(e.g. JPA, Hibernate, JDO 등)을 사용하기 용이
  • 단, 모든 기술에 대해 세분화된 예외가 전부 구현된 것은 아니므로, 어느정도 추상화된 공통 예외를 사용해야 함 (e.g. DuplicateKeyException은 JDBC에 대해서만 발생, 하이버네이트의 경우 DataIntegrityViolation으로 발생)


템플릿-콜백 패턴
  • 전략 패턴의 구조를 가지나, 익명 내부 클래스로 전략을 생성하여, 이를 넘겨주는 형태의 패턴
  • 템플릿
    • 전략 패턴의 컨텍스트
    • 즉, 전략을 수행하기 전/후의 작업이나 전략 수행 과정을 정의한 클래스
  • 콜백
    • Functional Object
    • 전략의 실행 과정을 기술한 오브젝트로, 다른 오브젝트의 메소드에 전달되는 오브젝트 
  • 스프링에는 다양한 자바 엔터프라이즈 기술에서 사용할 수 있도록 미리 만들어져 제공되는 수십가지 템플릿/콜백 클래스와 API가 존재

JdbcTemplete

  • 스프링에서 제공하는 템플릿-콜백 형태의 JdbcTemplete




단위 테스트 (Unit Test)

  • 주로 클래스/메소드 단위로 수행하는 작은 단위의 테스트
  • 주로 프로그래머에 의해 만들어지므로, 프로그래머 테스트라고 하기도 함


JUnit

  • 자바 단위 테스트 프레임워크
  • 사용 방법
    • @Test
      • 메소드에 @Test 어노테이션을 부여하고 JUnit을 실행하면 테스트를 수행
    • assertThat
      • 2개의 매개변수를 (조건에 의해) 비교하여, 올바르지 않을 경우 예외를 발생
    • @Test(expect=[Exception 종류].class)
      • 특정 Exception이 발생함을 검증하기 위해 사용하는 어노테이션
    • @Before, @After
      • 매 JUnit 테스트 케이스를 실행하기 전후에 수행할 메소드에 사용하는 어노테이션
      • 이 어노테이션은 매 테스트 케이스마다 실행되므로, 모든 테스트에 공통으로 사용하는 정보나 오브젝트(Fixture, 픽스쳐)의 경우 메소드 추출 등의 방식으로 처리하는 것이 나음
    • @BeforeClass, @AfterClass
      • 테스트 클래스 전체에 걸쳐 한번만 실행되는 static 메소드
    • 스프링 테스트 컨텍스트 프레임워크
      • @RunWith(SpringJUnit4ClassRunner)
      • @ContextConfituration(locations="/applicationContext.xml")

테스트 주도 개발 (TDD, Test Driven Development)

  • 테스트 코드를 먼저 만들고, 테스트를 성공하게 해주는 코드를 작성하는 방식의 개발 방법
  • 장점: 모든 개발 코드에 대해 테스트가 수행됨 
  • Test First Development

침투적(invasive) 기술 vs 비침투적(noninvasive) 기술
  • 침투적 기술
    • 특정 기술을 사용하기 위해 API나 인터페이스를 강제하는 기술
  • 비침투적 기술
    • 특정 기술을 코드에 영향을 주지 않고 적용 가능한 기술


동등 분할 (equivalence partitioning)

  • 같은 결과를 내는 값의 범위를 구분하여 각 대표 값으로 테스트하는 방법


경계값 분석 (boundary value analysis)

  • 동등 분할 범위의 경계값을 이용해 테스트 (숫자일때 0, 정수의 최대값, 최소값 등으로 테스트)


관심사의 분리 (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. 마틴)

책을 구입한지 어언... 

1년이 되어가는 것 같다...


그동안 이런 핑계, 저런 핑계로 책을 읽지 못했다... 

그 중 가장 큰 이유는 아마도 나약한 내 정신력과

그냥 되는 대로 살자 식의 인생과의 합의? 


물론, Spring 관련된 교육을 일부 받긴 했지만...

일단 현재 종사 분야가 그리 Spring을 접할 만한 기회가 없기에 

많은 부분을 까먹은 것 같다. 


다시 공부를 시작할 겸해서

책에 있는 예제들이나 중요 개념을 내 나름대로 정리할 예정이다. 


책에 있는 것만 따라하는 건 그리 좋은 방법이 아닌 것 같다.

내 나름대로 진행하면서 그동안 공부했던 다른 툴이나 기술을 활용하여

예제를 완성해나가는 것도 나름 재미있을 것 같다. 


일단... 꾸준히 한번 시작해보자... 


+ Recent posts