- 浏览: 80932 次
- 性别:
- 来自: 北京
考虑使用 Singleton 模式 时拥有子类别的问题,在Singleton模式中的getInstance()通常是一个静态方法,不能在子类别中重新定义它,关于子类别实例的产生交由getInstance()来进行是最好的选择,例如:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示系统环境变数
String style = getEnv("style");
if (style.equals("child1"))
instance = new ChildSingleton1();
else if (style.equals("child2r"))
instance = new ChildSingleton2();
else
instance = new Singleton();
}
return _instance;
}
// ....
}
上面这个程式片段改写自 Gof 书中关于Singleton的例子,并用Java实现;在书中指出,这个例子的缺点是每增加一个子类别,getInstance()就必须重新修改,这个问题在Java中可以使用Reflection机制来解决:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示环境变数
String style = getEnv("style");
try {
instance = (Singleton)
Class.forName(style).newInstance();
}
catch(Exception e) {
System.out.println(
"Sorry! No such class defined!");
}
}
return instance;
}
// ....
}
上面的方式使用了Java的Reflection机制,并透过环境变数设定要产生的子类Singleton,如果不使用Reflection的话,Gof 书中提出的改进方法是使用Registry of Singleton方法:
import java.util.*;
public class Singleton {
// 注册表,用于注册子类别物件
private static Map registry = new HashMap();
private static Singleton instance;
public static void register(
String name, Singleton singleton) {
registry.put(name, singleton);
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示取得环境变数
String style = getEnv("style");
instance = lookup(style);
}
return instance;
}
protected static Singleton lookup(String name) {
return (Singleton) registry.get(name);
}
}
在Gof书中使用List来实现注册表,而在这边使用HasMap类别来实现,它是由Java SE所提供的;在父类别中提供一个register() 以注册Singleton的子类别所产生之实例,而注册的时机可以放在子类别的建构方法中加以实现,例如:
public class ChildSingleton1 extends Singleton {
public ChildSingleton1() {
// ....
// 注册子类别物件
register(getClass().getName(), this);
}
}
若要利用Singleton,则先使用这个子类别产生物件,这会向父类别注册物件,之后透过Singleton父类别来取得物件:
// 必须先启始这段注册程序
// 产生并注册ChildSingleton1物件
new ChildSingleton1();
// 产生并注册ChildSingleton2物件
new ChildSingleton2();
// 注册完成,可以使用父类别来取得子类的Singleton
// 至于取回何哪一个,视您的环境变数设置决定
Singleton childSingleton = Singleton.getInstance();
这种方式的缺点是您必须在程式中启始一段程序,先向父类别注册子类的Singleton,之后才能透过父类别来取得指定的子类别Singleton实例, 好处是可以适用于没有Reflection机制的语言,如果您想要改变Singleton父类传回的子类Singleton,可以在上面的 Singleton类别中加入一个reset()方法,将instance设定为null,然后重新设定环境变数,之后再利用 Singleton父类的getInstance()方法重新取得注册表中的其它子类。
事实上Registry of Singleton的真正优点正在于此,您可以使用父类别来统一管理多个继承的子类别之Singleton实例,您可以在需要的时候再向父类别注册子类 Singleton,必要时随时调整传回的子类别Singleton。
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示系统环境变数
String style = getEnv("style");
if (style.equals("child1"))
instance = new ChildSingleton1();
else if (style.equals("child2r"))
instance = new ChildSingleton2();
else
instance = new Singleton();
}
return _instance;
}
// ....
}
上面这个程式片段改写自 Gof 书中关于Singleton的例子,并用Java实现;在书中指出,这个例子的缺点是每增加一个子类别,getInstance()就必须重新修改,这个问题在Java中可以使用Reflection机制来解决:
public class Singleton {
private static Singleton instance = null;
private Singleton() {
// ....
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示环境变数
String style = getEnv("style");
try {
instance = (Singleton)
Class.forName(style).newInstance();
}
catch(Exception e) {
System.out.println(
"Sorry! No such class defined!");
}
}
return instance;
}
// ....
}
上面的方式使用了Java的Reflection机制,并透过环境变数设定要产生的子类Singleton,如果不使用Reflection的话,Gof 书中提出的改进方法是使用Registry of Singleton方法:
import java.util.*;
public class Singleton {
// 注册表,用于注册子类别物件
private static Map registry = new HashMap();
private static Singleton instance;
public static void register(
String name, Singleton singleton) {
registry.put(name, singleton);
}
public static Singleton getInstance() {
if (instance == null) {
// getEnv表示取得环境变数
String style = getEnv("style");
instance = lookup(style);
}
return instance;
}
protected static Singleton lookup(String name) {
return (Singleton) registry.get(name);
}
}
在Gof书中使用List来实现注册表,而在这边使用HasMap类别来实现,它是由Java SE所提供的;在父类别中提供一个register() 以注册Singleton的子类别所产生之实例,而注册的时机可以放在子类别的建构方法中加以实现,例如:
public class ChildSingleton1 extends Singleton {
public ChildSingleton1() {
// ....
// 注册子类别物件
register(getClass().getName(), this);
}
}
若要利用Singleton,则先使用这个子类别产生物件,这会向父类别注册物件,之后透过Singleton父类别来取得物件:
// 必须先启始这段注册程序
// 产生并注册ChildSingleton1物件
new ChildSingleton1();
// 产生并注册ChildSingleton2物件
new ChildSingleton2();
// 注册完成,可以使用父类别来取得子类的Singleton
// 至于取回何哪一个,视您的环境变数设置决定
Singleton childSingleton = Singleton.getInstance();
这种方式的缺点是您必须在程式中启始一段程序,先向父类别注册子类的Singleton,之后才能透过父类别来取得指定的子类别Singleton实例, 好处是可以适用于没有Reflection机制的语言,如果您想要改变Singleton父类传回的子类Singleton,可以在上面的 Singleton类别中加入一个reset()方法,将instance设定为null,然后重新设定环境变数,之后再利用 Singleton父类的getInstance()方法重新取得注册表中的其它子类。
事实上Registry of Singleton的真正优点正在于此,您可以使用父类别来统一管理多个继承的子类别之Singleton实例,您可以在需要的时候再向父类别注册子类 Singleton,必要时随时调整传回的子类别Singleton。
发表评论
-
组合or继承
2013-05-27 11:54 822到底使用组合还是继承是每本讲设计的资料里都要讨论一番的话题 ... -
Java访问控制private之我见
2013-05-24 11:36 783最近待业在家,遂有空重新读了thinking in Java这 ... -
XML 系列教程
2012-05-06 12:50 586http://www.w3school.com.cn/x.as ... -
面向接口编程详解
2012-04-19 21:42 1107面向接口编程详解 2009-04-23 作者:张洋 来源: ... -
浅析java回调机制与观察者模式
2012-04-10 17:23 17901 java回调机制: 首先解 ... -
Java程序设计之-复合优先于继承
2012-04-03 10:33 1443组合 通过创建一个由其他对象组合的对象来获得新功能的重用方法 ... -
java学习之路(转)
2012-03-30 15:01 762(一) 从事软件 ... -
java内部类
2012-03-28 16:26 854一、 定义 放在一个类的内部的类我们就叫内部类。 二、 作用 ... -
为什么匿名内部类只能访问其所在方法中的final变量(转)
2012-03-28 15:45 1030(1).所谓“局部内部类”就是在对象的方法成员内部定义的类。而 ... -
Java访问权限修饰符(转)
2012-03-28 11:20 10611、Class类的访问权限: ... -
【java】好书推荐
2012-03-26 15:31 1439Java软件架构师所要需的东西 作为Java程序员来说,最痛 ... -
Java绝对好文,转载的!(转载)
2012-03-25 14:45 791想来学习Java也有两个年头了,永远不敢说多么精通,但也想谈谈 ... -
理解java动态加载机制
2012-03-20 00:01 10071.java动态性 java是一种 ... -
热部署、热加载
2012-03-19 14:14 3659不重启Tomcat有两种方式:热部署、热加载 热部署:容 ... -
单例模式(Singleton Pattern)
2012-03-05 20:40 6806.单例模式(Singleton Pattern) 前面说提到 ... -
java.util.concurrent 多线程框架
2012-02-26 16:15 759http://daoger.iteye.com/blog/14 ... -
线程----BlockingQueue (转),java
2012-02-26 13:50 792/** 本例介绍一个 ... -
关于多个线程同时调用单例模式的对象,该对象中方法的局部变量是否会受多个线程的影响
2012-02-12 12:16 2905对于那些会以多线程运行的单例类,例如Web应用中的Servle ... -
Java线程同步机制synchronized关键字的理解
2011-12-25 14:34 734由于同一进程的多个线 ... -
synchronized与static synchronized 的区别
2011-12-24 22:48 6491.synchronized与static synchroni ...
相关推荐
Design Pattern: Registry of Singleton 模式 Design Pattern: Default Adapter 模式 31 Design Pattern: Adapter 模式 - Object Adapter 32 Design Pattern: Adapter 模式 - Class Adapter 36 Design Pattern: ...
Files contained in registry-3.1.3.jar: META-INF/MANIFEST.MF com.ice.jni.registry.RegMultiStringValue.class com.ice.jni.registry.RegBinaryValue.class com.ice.jni.registry.RegistryException.class ...
Windows Registry Forensics: Advanced Digital Forensic Analysis of the Windows Registry, Second Edition, provides the most in-depth guide to forensic investigations involving Windows Registry....
讲述了如何部署registry、registry-web的部署,以及registry-web如何管理registry私库的镜像上传、下载的授权、镜像删除、用户管理
META-INF/MANIFEST.MF com.ice.jni.registry.HexNumberFormat.class com.ice.jni.registry.NoSuchKeyException.class com.ice.jni.registry.NoSuchValueException.class com.ice.jni.registry.RegBinaryValue.class ...
Laravel开发-laravel-registry Laravel注册表模式的实现
docker官方镜像仓库registry离线包,使用docker load -i registry.tar
Registry
赠送jar包:micrometer-registry-prometheus-1.8.2.jar 赠送原API文档:micrometer-registry-prometheus-1.8.2-javadoc.jar 赠送源代码:micrometer-registry-prometheus-1.8.2-sources.jar 包含翻译后的API文档...
Windows Registry Forensics Advanced Digital Forensic Analysis of the Windows Registry Harlan Carvey brings readers an advanced book on Windows Registry. The first book of its kind EVER -- Windows ...
Could not resolve dependencies for project org.apache.flink:flink-avro-confluent-registry:jar:1.15.3: Could not find artifact io.confluent:kafka-schema-registry-client:jar:6.2.2 in maven 安装本地...
解决动态链接库ICE_JNIRegistry.dll位置放置问题,该jar包中已经...该压缩包中有regist.jar和registry源码,regist.jar是将registry-3.1.3的源码修改后重新编译的,不需要ICE_JNIRegistry.dll,直接调用regist.jar即可
Structuring of Services in the Registry .
Registry Workshop: Registry Workshop 是一款高级的注册表编辑工具,能够完全替代 WIndows 系统自带的 RegEdit 注册表编辑器。
该文档为docker-registry的搭建步骤,由于原生的docker-registry没有提供web界面,需要安装docker-registry-web。本文档包含了所有安装步骤。原创
Registry snap - make snap of registry 註冊表快照
RegistryKey registryKey = Registry.openSubkey(Registry.HKEY_CURRENT_USER, Internet, RegistryKey.ACCESS_READ); // 注册表表项键 RegistryValue registryValue = registryKey.getValue("ProxyEnable"); ...
dubbo registry
dockerhub经常访问不了,特地将registry下载到本地,供大家学习使用
Registry Workshop 4.3.0汉化破解版 Registry Workshop 4.3.0汉化破解版 Registry Workshop 4.3.0汉化破解版 Registry Workshop 4.3.0汉化破解版 可批量删除注册表文件, 使用方法请参考我的百度博客: ...