登记式单例模式

刚看完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 {
	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值