六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 34|回复: 0

Java模式设计之单例模式(登记模式)

[复制链接]

升级  12.67%

15

主题

15

主题

15

主题

秀才

Rank: 2

积分
69
 楼主| 发表于 2013-2-3 10:41:51 | 显示全部楼层 |阅读模式
登记式单例类

登记式单例类是GoF 为了克服饿汉式单例类及懒汉式单例类均不可继承的缺点而设计的。本书把他们的例子翻译为Java 语言,并将它自己实例化的方式从懒汉式改为饿汉式。只是它的子类实例化的方式只能是懒汉式的, 这是无法改变的。如下图所示是登记式单例类的一个例子,图中的关系线表明,此类已将自己实例化。



代码清单3:登记式单例类

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) );
            }
            /**
            * 一个示意性的商业方法
            */
            public String about()
            {
            return "Hello, I am RegSingleton.";
            }
            }

它的子类RegSingletonChild 需要父类的帮助才能实例化。下图所示是登记式单例类子类的一个例子。图中的关系表明,此类是由父类将子类实例化的。



下面是子类的源代码。

代码清单4:登记式单例类的子类

import java.util.HashMap;
            public class RegSingletonChild extends RegSingleton
            {
            public RegSingletonChild() {}
            /**
            * 静态工厂方法
            */
            static public RegSingletonChild getInstance()
            {
            return (RegSingletonChild)
            RegSingleton.getInstance(
            "com.javapatterns.singleton.demos.RegSingletonChild" );
            }
            /**
            * 一个示意性的商业方法
            */
            public String about()
            {
            return "Hello, I am RegSingletonChild.";
            }
            }

在GoF 原始的例子中,并没有getInstance() 方法,这样得到子类必须调用的getInstance(String name)方法并传入子类的名字,因此很不方便。本章在登记式单例类子类的例子里,加入了getInstance() 方法,这样做的好处是RegSingletonChild 可以通过这个方法,返还自已的实例。而这样做的缺点是,由于数据类型不同,无法在RegSingleton 提供这样一个方法。由于子类必须允许父类以构造子调用产生实例,因此,它的构造子必须是公开的。这样一来,就等于允许了以这样方式产生实例而不在父类的登 记中。这是登记式单例类的一个缺点。

GoF 曾指出,由于父类的实例必须存在才可能有子类的实例,这在有些情况下是一个浪费。这是登记式单例类的另一个缺点。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表