네트워크 게임을 만들고있고, UserInfo
클래스를 딱 한번만 만들 필요가 있어서, Singleton 생각이 났다.
로그인 할때 UserInfo를 생성하고, 필요할때마다 다른 스레드, 액티비티 들에서 부르려고 했다.
// Singleton
public class UserInfo {
private String userName;
private NetworkObj networkObj;
public UserInfo(String userName, NetworkObj networkObj) {
this.userName = userName;
this.networkObj = networkObj;
}
public UserInfo() {
}
private static class LazyHolder {
public static final UserInfo uniqueInstance = new UserInfo();
}
public static UserInfo getInstance() {
return LazyHolder.uniqueInstance;
}
// Getter..
}
이렇게 코드를 짰었다. 하지만 이건 엉터리. 완전 틀렸다.
싱글턴은, 딱 한번만 초기화 되어야 해서 싱글턴이다.
만약 생성자에 매개변수를 달아 초기화 하고자 한다면 그것은 싱글턴이 아닐 것이다.
특히 나처럼 lazy holder 기법으로 코드를 짰다면 getInstance()
를 통해서만 호출해야 할것이다.(생성자가 아니라)
싱글턴 객체에 data를 넘기고 싶다면 두가지 옵션이 있다:
SingletonObj singleton = SingletonObj.getInstance();
singleton.init(paramA, paramB); // init the object with data
SingletonObj singleton = SingletonObj.getInstance();
singleton.doSomething(paramA, paramB); // pass parameters on execution
초기화 후에 데이터를 넘겨주는 것이다.
// Singleton
public class UserInfo {
private String userName;
private NetworkObj networkObj;
public UserInfo() {}
public void init (String userName, NetworkObj networkObj) {
this.userName = userName;
this.networkObj = networkObj;
}
private static class LazyHolder {
public static final UserInfo uniqueInstance = new UserInfo();
}
public static UserInfo getInstance() {
return LazyHolder.uniqueInstance;
}
// Getter..
}
❗❗ 결론: 싱글턴의 초기화는 파라미터(매개변수) 없이 되어야 한다.