轻巧掌握单例模式的理论与应用

轻松掌握单例模式的理论与应用
  • 单例模式中有以下三个特点:
  1. 静态的私有变量.
  2. 私有的构造方法.
  3. 公共的静态入口方法
  • 那么在什么场景下适合用单例模式呢?

     如果这个类中没有可以修改的成员变量,也就是说这个类没有状态,如果存在可以修改成员变量的话就会产生线程安全的问题,所以不建议使用.因为单例模式无法继承,所以也没有办法扩展,无法扩展其实现.比较适合单例模式是在读取配置文件的场景.

          上面的内容是来自一个同学写的博客,个人认为将他写的单例模式与我这篇写的单例模式结合起来学习,会更加清楚一些。原文链接http://blog.csdn.net/jnqqls/article/details/7928144

  • 单例模式实战应用:

在DRP学习中,一个业务逻辑层的类也进行单例模式的封装,代码如下:

/**
 * 采用单例管理用户
 * @author Administrator
 *
 */
public class UserManager {

	//静态私有变量
	private static UserManager instance = new UserManager();
	
	//私有构造方法
	private UserManager() {}
	
	//公有静态方法,用来获得唯一的UserManager对象
	public static UserManager getInstance() {
		return instance;
	}

  我们都知道单例模式主要是为了对象的计划生育,从未避免了对象的泛滥实例化,也就节省了内存资源。掌握了单例模式的主要思想,就要学会怎样使用单例模式。看下面的代码

User_add.jsp页面

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%@ page import="com.bjpowernode.drp.sysmgr.domain.*" %> 
<%@ page import="com.bjpowernode.drp.sysmgr.manager.*" %>   
<%
	String command = request.getParameter("command");
	String userId = "";
	String userName = "";
	String contactTel = "";
	String email = "";
	if ("add".equals(command)) {	
	
	       //这里就利用了上面单例UserManager类的getInstance方法获得全局一个UserManager类对象instance
		if (UserManager.getInstance().findUserById(request.getParameter("userId")) == null) { 
			User user = new User();
			user.setUserId(request.getParameter("userId"));
			user.setUserName(request.getParameter("userName"));
			user.setPassword(request.getParameter("password"));
			user.setContactTel(request.getParameter("contactTel"));
			user.setEmail(request.getParameter("email"));
			
			UserManager.getInstance().addUser(user);
			out.println("添加用户成功!");
		}else {
			userId = request.getParameter("userId");
			userName = request.getParameter("userName");
			contactTel = request.getParameter("contactTel");
			email = request.getParameter("email");
			out.println("用户代码已经存在,代码=【" + request.getParameter("userId") + "】");		
		}
	}


再看User_modify.jsp页面

<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<%@ page import="com.bjpowernode.drp.sysmgr.manager.*" %>
<%@ page import="com.bjpowernode.drp.sysmgr.domain.*" %>    
<%
	
   //主页面提交过来修改用户ID,页面查询,并加载到修改页面;
	String command = request.getParameter("command");
	String userId = request.getParameter("userId");
	
	//这里也是通过单例UserManager类获取了全局的(同一个)UserManager类的对象instance
	User user = UserManager.getInstance().findUserById(userId);
	
	//提交表单,判断是否提交,提交的话,设置提交参数
	if ("modify".equals(command)) {
		//user = new User();
		user.setUserId(request.getParameter("userId"));
		user.setUserName(request.getParameter("userName"));
		user.setPassword(request.getParameter("password"));
		user.setContactTel(request.getParameter("contactTel"));
		user.setEmail(request.getParameter("email"));
		
		UserManager.getInstance().modifyUser(user);
		out.println("修改用户成功!");
	}
%>

我的迷惑:代码虽然是这么写的,但感觉程序运行起来后,单例模式怎么就是生成一个对象?

解答迷惑:根据上面UserManager类中的静态对象instance,都知道任何静态变量的生存期将延续到整个程序的终止,所以在整个程序运行的过程中UserManager类型的对象始终都是一个对象instance。在user_add.jspuser_modify.jsp页面里调用的UserManager.getInstance获得的对象都是同一个。这样就达到了对象实例化的唯一性和节省内存资源。