티스토리 뷰
발생일: 2009.12.15
문제:
친구 홍이 문제점에 봉착했다며 묻는다.
문제:
친구 홍이 문제점에 봉착했다며 묻는다.
Abstract Class 를 어떻게 Singleton 으로 만들 수 있을까?
Abstract Class 를 상속한 클래스들은 다 싱글턴으로 구현되도록 해야 한다고 한다.
음...
그럼 Abstrac class 안에 싱글턴 패턴인 getInstance 를 구현하되,
그 안에 팩토리 메서드 패턴으로 동적 타입으로 만들 수 있게 하면 안될까...?
private static AbstractSingleton uniqueInstance;
public static AbstractSingleton getInstance(Class cls) {
// uniqueInstance 가 존재하는지 확인
// 없을 경우, 동기화해서 class 에 따라 객체 생성해서 리턴
// 있을 경우, uniqueInstance 리턴
}
이렇게 말이야...
음.... 가만,..
근데 이렇게 하면 uniqueInstance 에 단 하나의 인스턴스가 들어가버린다.
(즉, 한 번에 다형성을 무시하고 한 객체 밖에 생성할 수가 없다.)
게다가 Abstract Class 를 상속받는 클래스의 생성자가 private 일 테니 컴파일 에러도 나겠군...-_-;;
이렇게 하면 안되겠다.
흠.... 어떻게 해야할까...
해결책:
추상 클래스를 상속받은 아이를 위와 같은 방법으로 싱글턴으로 구현하는 건 불가능하다.
다만, 편법이 있으니, 아래와 같이 스태틱으로 인스턴스의 레지스트리를 만든 후에,
getInstance 에서 인스턴스에 저장된 값을 돌려주는 방법이 있다.
public abstract class AbstractSingleton {
= new HashMap<Class<? extends AbstractSingleton>, AbstractSingleton>();
public static AbstractSingleton getInstance(Class<? extends AbstractSingleton> cls)
throws InstantiationException, IllegalAccessException {
if (instances.get(cls) == null) {
synchronized (instances) {
if (instances.get(cls) == null) {
instances.put(cls, cls.newInstance());
}
}
}
return instances.get(cls);
}
public abstract void setName(String name);
public abstract String getName();
}
이 클래스를 상속받아 구현하는 서브 클래스는 아래와 같은 모습이다.
public class ConcreteSingleton extends AbstractSingleton {
public String name;
ConcreteSingleton() {} // private으로 구현하면 안된다. 기본 생성자로 만든다.
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
객체 생성은 아래와 같이 사용한다.
public class AbstractSingletonTest {
public static void main(String[] args)
throws InstantiationException, IllegalAccessException {
// 객체를 생성한다.
AbstractSingleton ac = AbstractSingleton.getInstance(ConcreteSingleton.class);
System.out.println(ac.getName()); // null
ac.setName("instance one"); // 객체의 이름을 설정한다
System.out.println(ac.getName()); // instance one 출력
// 두번 째 객체를 생성한다. 저장된 객체를 리턴한다.
AbstractSingleton acOther = AbstractSingleton.getInstance(ConcreteSingleton.class);
System.out.println(acOther.getName()); // instance one 출력
}
}
안타깝게도, AbstractSingleton 클래스를 상속받는 서브 클래스의 생성자를 private 으로 설정할 수 없다.
다만 AbstractSingleton 클래스와 그 서브 클래스를 같은 패키지에 두고,
default 접근자로 작성하여 다른 패키지에서 해당 객체를 생성할 수 없도록 제한하는 정도에 만족해야겠다.
더 자세한 내용은 아래 페이지를 참고하자.
반응형
댓글
공지사항