Item36. 비트 필드 대신 EnumSet을 사용하라

열거한 값들이 주로 집합으로 사용될 경우, 예전에는 각 상수에 서로 다른 2의 거듭제곱 값을 할당한 정수 열거 패턴을 사용해왔다.

다음과 같이 비트별 OR를 사용해 여러 상수를 하나의 집합으로 모을 수 있으며, 이렇게 만들어진 집합을 bit field라 한다.

1
2
3
4
5
6
7
8
9
10
public class Text {

public static final int STYLE_BOLD = 1 << 0;
public static final int STYLE_ITALIC = 1 << 1;
public static final int STYLE_UNDERLINE = 1 << 2;
public static final int STYLE_STRIKETHROUGH = 1 << 3;
// 매개변수 styles는 0개 이상의 STYLE_상수를 비트별 OR한 값
public void applyStyles(int styles){...}

}

bit field의 문제점은 비트별 연산을 통해 집합 연산은 효율적으로 수행할 수 있으나, 정수 열거 상수의 단점들에 추가로 비트 필드값이 그대로 출력되면 해석하기 더 어렵다는 단점이 있다.

Read more

Front Controller Pattern

Front controller pattern

front controller pattern 은 주로 web 환경에서 client 요청이 들어오면 먼저 공통적인 로직을 처리하는 하나의 controller를 두고, 해당 controller가 적합한 controller 를 호출하는 패턴이다.

front controller의 정확한 정의는 다음과 같다.

Front Controller is defined as “a controller that handles all requests for a Web site”. It stands in front of a web-application and delegates requests to subsequent resources. It also provides an interface to common behavior such as security, internationalization and presenting particular views to certain users

(ref - https://www.baeldung.com/java-front-controller-pattern)

Front controller pattern의 장점

  • front controller 가 결국 모든 controller이전에 수행됨으로 controller에서 발생할 수 있는 공통로직을 front controller에서 처리하고, 중복코드를 제거하고 유지보수성을 높여준다.
  • front controller를 제외한 나머지 controller는 servlet을 사용하지 않아도 된다.

Front controller pattern 은 MVC pattern과 함께 자주 쓰인다. 대표적으로 spring framework에서 사용하고 있으며,org.springframework.servlet.dispatcherServlet이 front controller이다.

UML diagram

front controller pattern은 front controller와 요청을 위임할 class (controller) 로 구성된다. 이떄 요청을 위임할 class는 공통 abstract class 또는 interface를 상속하고 있다.

Read more

packet switching

network 구성 요소

  • network edge : application (ex) web server ) , host
  • network core : routers
  • communication link : network 구성요소들을 이어주는 물리적인 cable

protocol

  • 둘 이상의 통신 개체간에 교환되는 메시지 포맷과 순서뿐 아니라 , 메시지의 송수신과 다른 이벤트에 따른 행동들을 정의한다. (통신매체간 통신 규약)

network core 내 router간 데이터 교환 방식

  1. circuit switching (회선 교환)

종단 system (network edge)간에 통신을 제공하기 위해 경로상에 필요한 자원 (link 전송률,buffer)를 통신 기간동안 미리 확보(예약) 해두는 방식

  1. packet switching(패킷 교환) : 현재 인터넷에서 사용중인 방식

circuit switching 방식과는 다르게 on-demand방식으로 네트워크 자원을 사용하기 떄문에 더 많은 사용자 수용가능

  • 송신측은 송신할 데이터를 packet이라고 하는 단위로 분할해서 송신.
  • router 에서 packet을 store-and-forwarding transmission (저장-후-전달 전송) 방식으로 전달함
Read more

Process

Process concept

  • program : disk 상에 존재하며, 명령어의 모음
  • process : program이 os로부터 메모리를 할당받아 실행중인 상태로 memory 부분이 code / data(전역변수,static 변수) / stack(지역변수,함수 매개변수,함수 return주소) / heap(malloc과 같은 system call을 호출하여 동적으로 할당되는 영역) 영역과 program counter 나뉜다

정확히 얘기하면 초기 OS 에서는 program의 전체 영역을 메모리에 올렸지만, 현대 OS에서는 필요한 영역만 메모리에 올리는 데 이 부분은 paging , swapping 과 관련된 개념이다.

(ref - https://gabrieletolomei.wordpress.com/miscellanea/operating-systems/in-memory-layout/ )

Process State

  • new state : process가 처음 메모리에 load된 상태
  • ready state : process가 cpu에 의해 실행될 수 있는 상태

ready state에서 OS의 scheduling 정책에 따라 cpu를 할당해줄 process를 선택한다. 선택된 process는 running state가 된다.

  • running state : process가 cpu에 의해 실행되고 있는 상태

running state에서는 3가지 state로 분기할 수 있다.

  1. ready state : OS는 선점형 (pre-emptive) 방식으로 time quantuam (일반적으로 10ms) 간격으로 process가 termination state 가 되지 않으면 timer interrupt를 걸어준다. (Time sharing , 시분할 시스템 ) 따라서 timer interrupt 된 process는 다시 ready state가 된다.
  2. waiting state : process가 I/O 요청시 I/O응답이 오기전까지 CPU는 다른 process를 실행한다. I/O 작업 완료전까지는 waiting state가 되고, I/O 작업이 완료되면 다시 ready state가 된다.
  3. termination state: process가 time quantuam이내에 정상 수행 종료된다.

정상 상태는 아니지만 예외적인 process 상태가 있다. UNIX system 에서는 zombie process 라고 부르는데 부모 process 가 fork() system call을 통해 부모 process와 동일한 code를 가진 자식 process를 생성하면 , 자식 process 는 exec() system call을 통해 새로운 code로 덮어씌워진 뒤 실행된다. 부모 process는 자식 process가 종료될떄까지 기다리고 자식 process 가 사용한 resource를 os에게 회수를 요청한다 (reaping)

부모 process , 자식 process 종료가 비정상적으로 일어났을때 나타날수 있는 process 상태는 다음과 같다.

  1. zombie process : 자식 process가 비정상적으로 종료되어 부모 process는 waiting 중인 상태로 child process 의 resource가 반납이 안되고 있는 상태

부모 process가 kernel에게 resource 회수를 요청하지 못하고 있는 상태로 memory 누수현상이 발생한다.

  1. orphan process : 반대로 parent process 가 wait() 하지않고 종료된 경우 자식 process는 orphan process가 된다.
Read more

MVC pattern

Model-View-Controller,MVC pattern은 사용자 인터페이스로부터 비즈니스 로직을 분리해서 application의 시각적인 요소에 변경사항이 비즈니스 로직에 영향없이 변경될 수 있도록 도와주는 패턴이다.

MVC 패턴은 Model , View , Controller로 구성되는데

  • Model : application의 데이터 , bussiness logic , business rule 을 뜻한다.
    *Model 을 뷰에 담을 데이터라고 한정적 정의하는 경우도 있고 (ref- https://developer.mozilla.org/ko/docs/Glossary/MVC)
    dao , service 계층의 business logic 을 모두 포함해 model 이라고 하는 경우도 있습니다.
    (ref - https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller)
    중요한 포인트는 UI와 application 비즈니스 로직을 분리시켜 서로 독립적으로 개발이 가능하도록 했다는 점입니다.
    dao, service , view에 대한 명확한 계층 구분은 multi-tier architecture에서 다루고 있습니다. (ref - https://en.wikipedia.org/wiki/Multitier_architecture)
  • View : 사용자 인터페이스 요소 (UI)
  • Controller : Model과 View 사이의 상호동작을 관리한다. 사용자의 요청에 따라 모델/뷰를 업데이트한다.

Read more

Item35. Enum type ordinal method 대신 member field를 사용하라

Enum type의 ordinal method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* Returns the ordinal of this enumeration constant (its position
* in its enum declaration, where the initial constant is assigned
* an ordinal of zero).
*
* Most programmers will have no use for this method. It is
* designed for use by sophisticated enum-based data structures, such
* as {@link java.util.EnumSet} and {@link java.util.EnumMap}.
*
* @return the ordinal of this enumeration constant
*/
public final int ordinal() {
return ordinal;
}

대부분 열거타입 상수는 하나의 정수값과 대응되는데, ordinal method는 특정 상수가 그 열거타입에서 몇번쨰 위치인지를 반환하는 method이다. 예를 들면 아래와 같이 합주단 종류 enum type내에서 몇번쨰 위치하고 있는지 알아낼때 사용한다.

1
2
3
4
5
6
7
8
9
public enum Ensemble {

SOLO,DUET,TRIO,QUARTET,QUINTET,
SEXTET,SEPTET,OCTET,NONET,DECET;

public int positionOfMusicians(){
return ordinal()+1;
}
}
Read more

Item34. int 상수 대신 열거 타입을 사용하라

Enum Type 정의

Enum type은 일정 개수의 상수 값을 정의한 다음 그 외의 값들은 허용하지 않는 타입이다. Enum Type은 다음과 같은 특징을 가지고 있다.

1
2
3
4
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}

(https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)

  1. enum type 자체는 java.lang.Enum 추상 class를 상속받고 있는 class이다. (Java에서는 중복 상속이 불가하므로 다른 class는 상속받을 수 없다.)
1
2
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {
  1. 상수당 자신의 instance를 하나씩 만들어 public static final 필드로 공개한다. (enum class내 상수는 public static final 필드와 같음 )

  2. 외부에서 접근할 수 있는 생성자를 제공하지 않는다. 때문에 singleton은 원소가 하나뿐인 열거타입이라고도 볼 수 있다.

Read more

Junit5 Parameterized Test

Parameterized Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class SetTest {
private Set<Integer> numbers;
@BeforeEach
void setUp(){
numbers = new HashSet<>();
numbers.add(1);
numbers.add(1);
numbers.add(2);
numbers.add(3);
}
@Test
void contains() {
assertThat(numbers.contains(1)).isTrue();
assertThat(numbers.contains(2)).isTrue();
assertThat(numbers.contains(3)).isTrue();
}
}

위와 같이 Set의 API에 대한 학습테스트를 수행한다고 하였을떄 각 원소를 포함했는지 중복코드가 발생한다.

Junit 5부터는 이를 ParameterizedTest 로 테스트에 여러개의 매개변수를 넣어주게 해줌으로써 테스트 코드 리팩토링을 원할하게 해준다.

필요한 library dependency는 다음과 같다.

1
2
3
4
5
6
7
8
9
10
// maven
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.8.1</version>
<scope>test</scope>
</dependency>

//gradle
testCompile("org.junit.jupiter:junit-jupiter-params:5.8.1")
Read more

Item 33. 타입 안전 이종 컨테이너를 고려하라

Generic은 Collection과 단일 원소 컨테이너에서도 흔히 사용된다.

1
2
3
Set<E>;
Map<K,V>;
ThreadLocal<T>;

이런 타입들의 경우 매개변수화되는 대상은 컨테이너 자신이다. 따라서 하나의 컨테이너에서 매개변수화 할 수 있는 타입의 수가 정해져있다.

Type safe heterogeneous container pattern

타입 안전 이종 컨테이너 패턴(Type safe heterogenous container pattern)

  • 컨테이너 대신에 컨테이너의 키값을 매개변수하는 방식

  • 일급 Collection : Collection을 Wrapping하면서, 그 외 다른 멤버 변수가 없는 상태로 Collection의 상태와 행위를 한곳에서 관리 (SRP)

    (ref- https://jojoldu.tistory.com/412)

Read more

Entity 기본 키 매핑 전략 - SEQUENCE/TABLE/IDENTITY

Entity - DB table mapping

Jpa를 사용해서 테이블과 매핑할 class를 @Entity를 필수로 붙여야하며, @Entity가 붙은 class를 entity라고 부른다.

@Entity 적용 시 다음과 같은 전제조건을 만족해야한다.

  1. 기본생성자
  2. final class , enum , interface , inner class가 아니여야 한다.
  3. 저장할 필드에 final 키워드가 붙으면 안된다.

Jpa는 다양한 mapping annotation을 지원하는데 , 크게 4가지로 분류될 수 있다.

  1. 객체와 테이블 매핑 : @Entity , @Table

  2. 기본 키 매핑 : @Id

  3. Field와 Column 매핑 : @Column

  4. 연관관계 매핑 ex) @ManyTone , @JoinColumn

기본키 매핑 전략

DB id값을 client측에서 넘겨줄 수 있겠지만, 인조키의 경우 DB vendor에서 생성할 수도 있다.
DB vendor 마다 기본키를 생성하는 방식이 다르다, 예를 들면 oracle에서는 sequence 객체를 만들고, mysql에서는 auto_increment기능을 사용한다.

Read more