刚看完gof的登记式单例,联想到spring容器的单例管理,根据自己的想法,写一个java语言的登记式单例模式,先记录下来。等看spring容器对bean的管理源码时再看其单例管理是如何实现的(spring容器应该是根据配置文件在加载时就用一个map缓存单例实例,取实例时根据scope属性在对应的缓存中找获取实例),然后对比学习。
下面是代码:
登记管理类
package com.shuidexiongdi.pattern.singleton.reg;
import java.util.HashMap;
import java.util.Map;
/**
* 单例注册管理类
* @author Djq
*
*/
public abstract class SingletonRegistryManager {
private static Map singletonMap = new HashMap();
/**
* 获取实例
* @param className
* @return
*/
public static Object getInstance(String className) {
if(isRegistred(className)) {
return singletonMap.get(className);
}
return null;
}
/**
* 获取实例
* @param clazz
* @return
*/
public static Object getInstance(Class clazz) {
return getInstance(clazz.getName());
}
/**
* 注册
* @param className
*/
public synchronized static void registry(String className) {
if(!singletonMap.containsKey(className)) {
try {
singletonMap.put(className, Class.forName(className).newInstance());
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 注册
* @param clazz
*/
public synchronized static void registry(Class clazz) {
registry(clazz.getName());
}
/**
* 反注册
* @param className
*/
public synchronized static void unRegistry(String className) {
if(singletonMap.containsKey(className)) {
singletonMap.remove(className);
}
}
/**
* 反注册
* @param clazz
*/
public synchronized static void unRegistry(Class clazz) {
unRegistry(clazz.getName());
}
public synchronized static boolean isRegistred(String className) {
return singletonMap.containsKey(className);
}
public synchronized static boolean isRegistred(Class clazz) {
return isRegistred(clazz.getName());
}
}
可注册为单例类的类:
package com.shuidexiongdi.pattern.singleton.reg;
public class SingletonOne {
protected SingletonOne () {
}
public static SingletonOne getInstance() {
if(SingletonRegistryManager.isRegistred(SingletonOne.class)) {
return (SingletonOne)SingletonRegistryManager.getInstance(SingletonOne.class);
}
return new SingletonOne();
}
}
测试:
package com.shuidexiongdi.pattern.singleton.reg.test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.shuidexiongdi.pattern.singleton.reg.SingletonOne;
import com.shuidexiongdi.pattern.singleton.reg.SingletonRegistryManager;
public class SingletonResgistryManagerTest {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void registry() {
assertFalse(SingletonRegistryManager.isRegistred(SingletonOne.class));
//注册
SingletonRegistryManager.registry(SingletonOne.class);
assertTrue(SingletonRegistryManager.isRegistred(SingletonOne.class));
}
@Test
public void unRegistry() {
//注册
SingletonRegistryManager.registry(SingletonOne.class);
//反注册
SingletonRegistryManager.unRegistry(SingletonOne.class);
assertFalse(SingletonRegistryManager.isRegistred(SingletonOne.class));
}
@Test
public void getInstance() {
//未注册
Object obj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNull(obj);
//注册
SingletonRegistryManager.registry(SingletonOne.class);
Object notObj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNotNull(notObj);
assertTrue(notObj instanceof SingletonOne);
//再次获取实例
Object notObj2 = SingletonRegistryManager.getInstance(SingletonOne.class);
assertSame(notObj, notObj2);
//反注册
SingletonRegistryManager.unRegistry(SingletonOne.class);
Object afterUnRegistryObj = SingletonRegistryManager.getInstance(SingletonOne.class);
assertNull(afterUnRegistryObj);
}
}
package com.shuidexiongdi.pattern.singleton.reg.test;
import static org.junit.Assert.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.shuidexiongdi.pattern.singleton.reg.SingletonOne;
import com.shuidexiongdi.pattern.singleton.reg.SingletonRegistryManager;
public class SingletonOneTest {
@Before
public void setUp() {
}
@After
public void tearDown() {
}
@Test
public void getInstance() {
//未注册单例
Object obj = SingletonOne.getInstance();
assertNotNull(obj);
//第二次获取
Object obj2 = SingletonOne.getInstance();
assertNotSame(obj, obj2);
//注册单例
SingletonRegistryManager.registry(SingletonOne.class);
Object afterRegObj = SingletonOne.getInstance();
assertNotNull(afterRegObj);
//第二次获取
Object afterRegObj2 = SingletonOne.getInstance();
assertSame(afterRegObj, afterRegObj2);
//反注册单例
//注册单例
SingletonRegistryManager.unRegistry(SingletonOne.class);
Object afterUnRegObj = SingletonOne.getInstance();
assertNotNull(afterUnRegObj);
//第二次获取
Object afterUnRegObj2 = SingletonOne.getInstance();
assertNotSame(afterUnRegObj, afterUnRegObj2);
}
}
package com.shuidexiongdi.pattern.singleton.reg.test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({SingletonOneTest.class, SingletonResgistryManagerTest.class})
public class TestAllSuite {
}
分享到:
相关推荐
### 登记式单例模式 登记式单例模式又称为注册式单例模式,它使用一个注册表(通常为HashMap)来管理所有单例对象。当需要某个单例对象时,先检查注册表中是否存在,如果不存在则创建并加入到注册表中。 #### 示例...
登记式单例模式虽然不是非常常见,但在某些情况下可以为管理多个单例对象提供方便。 #### 六、总结 单例模式是软件设计中的一个重要组成部分,特别是在Android开发中,它可以帮助我们更好地管理资源和服务。不同的...
单例模式分为三种:懒汉式单例、饿汉式单例、登记式单例。下面对单例模式的特点、实现方式和应用场景进行详细介绍。 单例模式的特点 1. 单例类只能有一个实例。 2. 单例类必须自己自己创建自己的唯一实例。 3. ...
登记式单例模式通常用于类似于Spring框架中的bean管理方式,即在单例类中维护一个容器或注册表,将类名及其对应的实例注册进去,之后可以通过查询注册表来获取相应的单例实例。 ##### 代码示例: ```java import ...
在 Java 中,单例模式的写法有好几种,主要有懒汉式单例、饿汉式单例、登记式单例等。 懒汉式单例是一种常见的单例模式实现方式,它在第一次调用的时候实例化自己。下面是懒汉式单例的四种写法: 1、基本懒汉式...
此外,登记式单例模式的一个优点是它可以被子类化,而饿汉式和懒汉式单例通常不支持。 在实际应用中,单例模式常见于以下场合: - **配置信息类**:如XML配置文件的解析,只创建一个解析器实例来读取和管理配置信息...
单例模式可以分为三种:懒汉式单例、饿汉式单例、登记式单例。 单例模式的要点 1. 某个类只能有一个实例 2. 它必须自行创建这个实例 3. 必须自行向这个系统提供这个实例 饿汉式单例类 饿汉式单例类是在类加载的...
7. **登记式/注册式单例**: 使用 Map 存储实例,适用于需要多个类似单例的场景。 ```java public class SingletonRegistry { private static final Map, Object> registry = new HashMap(); public static ...
在Java中,通常有三种常见的单例实现方式:懒汉式单例、饿汉式单例和登记式单例。 1. **懒汉式单例**: 懒汉式单例的特点是在类加载时不创建实例,而是等到第一次调用`getInstance()`方法时才创建。这样可以延迟...
单例模式的实现饿汉式懒汉式线程安全的懒汉式登记式单例模式的优缺点单例模式的优点单例模式的缺点 单例模式是23个模式中比较简单的模式,应用也非常广泛 什么是单例模式? 单例模式的定义: Ensure a class ...
登记式单例通过一个注册表来存储所有已创建的实例,适用于需要按名称获取单例的情况。这种方式线程安全,但增加了系统复杂性。 ```java public class RegSingleton { private static Map, RegSingleton> m_...
单例模式是 Java 中一种常见的设计模式,分为懒汉式单例、饿汉式单例和登记式单例三种。单例模式有以下特点: 1. 单例类只能有一个实例。 2. 单例类必须自己创建自己的唯一实例。 3. 单例类必须给所有其他对象提供...
登记式单例是一种更高级的单例模式,它可以管理多个单例类。下面是一个登记式单例的实现示例: ```java public class RegSingleton { private static Map, RegSingleton> m_registry = new HashMap(); static { ...
在Java中,有三种常见的实现方式:懒汉式单例、饿汉式单例和登记式单例。 1. **懒汉式单例**: 懒汉式单例的特点是在类首次被使用时才创建实例,即延迟初始化。这种方式的优点是如果程序始终没有使用到单例,那么...
- **登记式单例**:也称为注册式单例,它维护一个存储单例对象的集合,当需要实例时,首先检查集合中是否存在,存在则直接返回,不存在则创建并添加到集合中。这种方式更加灵活,可以管理一组单例对象,但实现相对...
在Java中,有三种常见的实现方式:懒汉式单例、饿汉式单例和登记式单例。 1. **懒汉式单例**: 懒汉式单例的特点是在类首次被需要时才创建实例,即延迟初始化。这种方式的优点是如果程序始终没有用到单例,就不会...
懒汉式单例模式在第一次调用`getInstance()`方法时才创建实例,因此比饿汉式节省了内存资源,但在多线程环境下需要考虑线程安全性。 ```java public class Singleton { private static Singleton theInstance =...