본문 바로가기
프로그래밍 놀이터/디자인 패턴, 리펙토링

[Effective Java] 타입 안전이 보장되는 혼성(heterogeneous) 컨테이너의 사용을 고려하자.

by 돼지왕왕돼지 2016. 11. 22.
반응형

 [Effective Java] 타입 안전이 보장되는 혼성(heterogeneous) 컨테이너의 사용을 고려하자.


1.5, atomicreference, Cast, checkedlist, checkedmap, checkedset, CLASS, class key, Class String, Class T, class 클래스, column, databaserow, Effective JAVA, heterogeneous, Integer.class, list, map, non-reifiable type, nosql, Set, single-element, string, String.class, string[], super type token, ThreadLocal, type, typesafe heterogeneous container, [Effective Java] 타입 안전이 보장되는 혼성(heterogeneous) 컨테이너의 사용을 고려하자., 값, 단일 요소, 단점, 리터럴 타입, 매개변수, 매개변수 갯수, 매개변수화, 모든 키, 비구체화 타입, 서로 다른 타입, 서로 타입, 수퍼 타입 토큰, 유연성, 저장 컨테이너, 제네릭, 제네릭화, 컨테이너, 컬렉션, 키, 타입 안전, 타입 안전 혼성 컨테이너, 토큰, 혼성, 혼성 컨테이너


-
제네릭은 Set 이나 Map 같은 컬렉션, ThreadLocal 이나 AtomicReference 같은 단일 요소(single-element) 저장 컨테이너에 가장 많이 사용된다.
이 컬렉션들은 컨테이너를 매개변수화 한 것이다.
컨테이너의 특성에 따라 사용 가능한 타입 매개변수의 갯수가 자연스럽게 제한된다.


-
타입 안전을 지키면서 더 큰 유연성을 갖기 위해서 ( 예를 들면 nosql 처럼 column 이 상황에 따라 다른 경우 )는
컨테이너 대신 키(key) 를 매개변수화 해주면 된다.


-
Class 클래스는 1.5부터 제네릭화되었다.
클래스 리터럴 타입은 Class 가 아니고 Class<T> 이다.
예) String.class 는 Class<String> 타입이고, Integer.class 는 Class<Integer> 타입이다.


-
Class 를 key 로 사용하면, 타입 안전이 보장되면서 혼성(heterogeneous)이다.
일반적인 Map 과 다르게 모든 키가 서로 다른 타입일 수 있고, 값고 서로 다른 타입일 수 있다.


public class Sth{

private Map<Class<?>, Object> mSth = ...;


public <T> void putSth( Class<T> type, T instance ){

...

}


public <T> T getSth( Class<T> type ){

return type.cast( mSth.get( type ) );

}

}


이런 녀석을 타입 안전 혼성 컨테이너(typesafe heterogeneous container) 라고 한다.


-
위의 혼성 컨테이너는 client 가 type 을 원천 타입의 형태로 사용하면 타입 안전을 쉽게 훼손시킬 수 있다.
따라서 다음과 같이 하는 것이 더 견고하다.

public <T> void putSth( Class<T> type, T instance ){

mSth.put( type, type.cast( instance ) );

}


checkedSet, checkedList, checkedMap 등이 이와 동일한 기법을 사용한다.


-
위의 혼성 컨테이너의 또 다른 단점은 비구체화 타입(non-reifiable type) 에 사용될 수 없다.
즉 String, String[] 은 저장할 수 있지만, LIst<String> 은 저장할 수 없다.
List<String>.class 가 없기 때문.
이는 수퍼 타입 토큰( super type token ) 기법을 사용할 수 있지만, 나름의 제약이 더 있다는 것..


-
컨테이너에 제네릭을 사용하면 컨테이너 당 사용 가능한 타입 매개변수의 숫자가 제한된다.
그러나 컨테이너 자체보다는 요소의 키에 타입 매개변수를 두면 그런 제약을 극복할 수 있다.
이 경우 서로 다른 타입의 요소가 저장될 수 있어 혼성 컨테이너라고 부른다.
타입 안전이 보장되는 혼성 컨테이너의 키로 Class 객체를 사용할 수 있다. 이런 방식으로 사용되는 Class 객체를 토큰이라고 하며, 독자적인 키 타입을 사용할 수도 있다.
데이터베이스 행을 나타내는 DatabaseRow 타입을 만들 수 있으며, 그것의 키로 Column<T> 제네릭 타입을 사용할 수 있다.





반응형

댓글0