Skip to content

Commit 5782df6

Browse files
committed
[ADD] Enforce the singleton property with a private constructor
1 parent 7301fe1 commit 5782df6

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,77 @@
11
### Item 3: private constructor나 enum type으로 singleton property를 강제해라.
22

3+
*Singleton*은 간단하게 클래스의 *Instantiated*(인스턴스화)가 정확히 한번만 진행된다.
4+
5+
*Single-tons*는 일반적으로 상태가 없는 객체나 함수 혹은 본질적으로 특별한 *system component* 들을 말한다.
6+
7+
**클래스를 싱글톤으로 만드는 것은 클라이언트의 테스트를 더 어렵게 한다.**
8+
9+
왜냐하면, 타입으로 사용되는 인터페이스를 구현하지 않는 한, singleton을 *mock implementation*(모의구현)으로 대신하는 것은 불가능하기 때문이다.
10+
11+
여기에 싱글톤을 구현하는 두 가지 일반적인 방법이 있다.
12+
13+
**Example Code #1**
14+
15+
```java
16+
// Singleton with public final field
17+
public class Road {
18+
public static final Road INSTANCE = new Road();
19+
private Road() {}
20+
21+
public void go() { ... }
22+
}
23+
```
24+
25+
이 방식으로 얻을 수 있는 장점은 **API**를 만들 때 그 클래스가 *singleton*임을 명백히 알 수 있다. 또한 더 단순하다.
26+
27+
**Example Code #2**
28+
29+
```java
30+
// Singleton with static factory
31+
public class Road {
32+
private static final Road INSTANCE = new Road();
33+
private Road() {}
34+
public static Road getInstance() { return INSTANCE; }
35+
36+
public void go() { ... }
37+
}
38+
```
39+
40+
이러한 *static factory method*를 통하여 얻을 수 있는 이점은 API를 바꾸지 않고도 싱글톤을 적용할 수 있다는 것이다.
41+
42+
또한, *generic singleton factory*를 사용할 수 있다.
43+
44+
마지막으로, *static factory**method reference**supplier*로써 사용할 수 있다는 것이다.
45+
46+
하지만, 단지 ``Serializable`` 을 상속하는 것으로는 충분하지 않다.
47+
48+
모든 *instance**field**transident*로 정의하고 ```readResolve``` 를 제공하지 않으면, *serialized**instance**deserialized* 될 때, 새 *instance*가 생성될 것이다.
49+
50+
이러한 일이 일어나는 것을 막기 위해서는, ```readResolve``` method를 정의하여야 한다.
51+
52+
```java
53+
// readResolve method가 singleton property를 보존한다.
54+
private Object readResolve() {
55+
return INSTANCE;
56+
}
57+
```
58+
59+
60+
61+
Singleton을 구현하는 세번째 방법은 *single-element enum*을 활용하는 것이다.
62+
63+
```java
64+
public enum Road {
65+
INSTANCE;
66+
67+
public void go() { ... }
68+
}
69+
```
70+
71+
위 방법은 *public field approach*와 유사하지만, 이것은 더 간결하다.
72+
73+
*serialization machinery*를 자유롭게 제공하고, *multiple instantiation*에서 안전하다.
74+
75+
이 접근 방식은 약간 부자연스러운 느낌을 줄 수 있지만, 이것은 **singleton을 구현하는데에 있어서 최고의 방법이다.**
76+
77+
만약에 당신의 *singleton*```Enum```이 아닌 다른 슈퍼클래스로 확장해야 하는 경우 이 방법을 사용할 수 없다는 것을 기억해라.

0 commit comments

Comments
 (0)