登记式单例类
登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。只是它的子类实例化的方式只能是懒汉式的, 这是无法改变的。
java 代码
- import?java.util.HashMap;??
- ??
- public?class?RegSingleton??
- {??
- ????static?private?HashMap?m_registry?=?new?HashMap();??
- ????static??
- ????{??
- ????????RegSingleton?x?=?new?RegSingleton();??
- ????????m_registry.put(x.getClass().getName(),?x);??
- ????}??
- ??
- ????/**?
- ?????*?保护的默认构造子?
- ?????*/??
- ????protected?RegSingleton()??
- ????{??
- ????}??
- ??
- ????/**?
- ?????*?静态工厂方法,返还此类惟一的实例?
- ?????*/??
- ????static?public?RegSingleton?getInstance(String?name)??
- ????{??
- ????????if?(name?==?null)??
- ????????{??
- ????????????name?=?"com.javapatterns.singleton.demos.RegSingleton";??
- ????????}??
- ????????if?(m_registry.get(name)?==?null)??
- ????????{??
- ????????????try??
- ????????????{??
- ????????????????m_registry.put(name,?Class.forName(name).newInstance());??
- ????????????}??
- ????????????catch?(Exception?e)??
- ????????????{??
- ????????????????System.out.println("Error?happened.");??
- ????????????}??
- ????????}??
- ????????return?(RegSingleton)?(m_registry.get(name));??
- ????}??
- ??
- }??
它的子类RegSingletonChild 需要父类的帮助才能实例化。
java 代码
- public?class?RegSingletonChild?extends?RegSingleton??
- {??
- ????public?RegSingletonChild()??
- ????{??
- ????}??
- ??
- ????/**?
- ?????*?静态工厂方法?
- ?????*/??
- ????static?public?RegSingletonChild?getInstance()??
- ????{??
- ????????return?(RegSingletonChild)?RegSingleton.getInstance("com.javapatterns.singleton.demos.RegSingletonChild");??
- ????}??
- ??
- }??
在GoF 原始的例子中,并没有getInstance() 方法,这样得到子类必须调用的getInstance(String name)方法并传入子类的名字,因此很不方便。此处在登记式单例类子类的例子里,加入了getInstance() 方法,这样做的好处是RegSingletonChild 可以通过这个方法,返还自已的实例。而这样做的缺点是,由于数据类型不同,无法在RegSingleton 提供这样一个方法。由于子类必须允许父类以构造子调用产生实例,因此,它的构造方法必须是公开的。这样一来,就等于允许了以这样方式产生实例而不在父类的登 记中。这是登记式单例类的一个缺点。
GoF 曾指出,由于父类的实例必须存在才可能有子类的实例,这在有些情况下是一个浪费。这是登记式单例类的另一个缺点。