单例模式

2021/7/16 java

# 单例模式

# 模式描述

  • 定义

    保证一个类仅有一个实例,并提供一个访问它的全局访问点

  • 优点

    提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。 因为该类在系统内存中只存在一个对象,所以可以节约系统资源。

  • 缺点

    没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

  • 模式类型

    懒汉/恶汉 安全/非安全

# 场景举例

  • 场景1:用户注册成功后,给予随机昵称作为用户对外展示信息,如何用单例模式实现?

    关键字:昵称库,随机,容器,单一实例

//第一步 构建单例昵称工具类

public class NickWordUtil {
	//昵称类库
    private List<String> setName = null;
    private NickWordUtil() {}

    private static NickWordUtil instance = new NickWordUtil();

    public static NickWordUtil getInstance() {
        return instance;
    }
 }
 
//第二步  提供初始化昵称库的访问点
public class NickWordUtil {
	//昵称类库
    private List<String> setName = null;
    private NickWordUtil() {}

    private static NickWordUtil instance = new NickWordUtil();

    public static NickWordUtil getInstance() {
        return instance;
    }
    
     /**
     * 初始化昵称库
     */
    public void setSensitiveWordMap(List<String> set){
        setName = set;
    }
 }
 
 //第三步  提供全局访问点
public class NickWordUtil {
	//昵称类库
    private List<String> setName = null;
    private NickWordUtil() {}

    private static NickWordUtil instance = new NickWordUtil();

    public static NickWordUtil getInstance() {
        return instance;
    }
    
     /**
     * 初始化昵称库
     */
    public void setSensitiveWordMap(List<String> set){
        setName = set;
    }
    
     /**
     * 随机返回昵称
     */
    public String getRandomName(){
        Collections.shuffle(setName);
        return setName.get(0);
    }
 }
 
 //第四步  容器实例化加载昵称库
 	/**
	 *
	 * 功能描述: 构建昵称库
	 *
	 * @param:
	 * @return:
	 * @auther: chenglibiao@itonghui.org
	 * @date: 2020/9/9 18:44
	 */
	@PostConstruct
	public void addNickWordDb() {
		String[] words = UserConstant.NICKNAMEJSON.split(",");
		NickWordUtil.getInstance().setSensitiveWordMap(Arrays.asList(words));
	}
	
	//第五步  全局调用
	String name = NickWordUtil.getInstance().getRandomName())

 
  • 场景2:对接外部或者第三方接口的一些配置参数信息,如何用单例模式实现?

# 注意事项

  • 懒汉模式下getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。