单例模式伪应用举例与其存在的意义

参考文献
单例模式VS静态方法 :http://www.cnblogs.com/seesea125/archive/2012/04/05/2433463.html
单例模式解说:  http://blog.csdn.net/guolin_blog/article/details/8860649
向原博主致敬!本文的出现主要基于以上两篇博客。为什么说是“单例模式伪应用举例”呢?实际生产环境是不会用实验中方法打印日志与获取数据库连接的,只是单例模式学习用。
场景

阅读完郭霖的单例模式解说,感觉那个小日志工具写的不错,这里自己再写一下,随便把以前学单例模式时写的数据库连接整到一起来复习。

问题来了:为什么使用单例模式而不是静态方法呢?单例模式就比静态方法好吗?

这关乎单例模式存在的意义:你挖空心思整一个单例模式出来,好像很有技巧的样子,可完全没有必要啊?单例能干的事情,静态方法都可以实现。

个人认为单例模式vs静态方法的讨论,实际上 是静态方法 与 非静态方法(实例方法)的讨论。比较赞同以下言论:

早期的结构化编程,几乎所有的方法都是“静态方法”,引入实例化方法概念是面向对象概念出现以后的事情了,区分静态方法和实例化方法不能单单从性能上去理解,创建c++,java,c#这样面向对象语言的大师引入实例化方法一定不是要解决什么性能、内存的问题,而是为了让开发更加模式化、面向对象化。这样说的话,静态方法和实例化方式的区分是为了解决模式的问题。

虽然都能实现目的,但是他们一个是基于对象,一个是面向对象的,就像我们不面相对象也能解决问题一样,面相对象的代码提供一个更好的编程思想。

也就是说,单例模式更加面向对象。现存的就是合理的,以后遇到这种类型的问题,也可以从应用历史发展的角度考虑,把注意力放到 每种方式实现的优点上来。

实验
单例实现日志工具 与获取数据库连接

package design;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * 单例模式
 * 定义:用单个的实例去有效地解决一类应用问题
 * 
 * 使用方法:
 * 1、定义一个该类的静态成员变量,并指向该类的唯一实例。
 * 2、私有化构造方法 3、定义一个静态方法返回该类唯一的实例
 * 
 * 伪应用举例:1、数据库连接  2、生产坏境日志的打印
 * 
 * @date 2016/3/18 10:30
 * @author Mr.Snail
 *
 */
public class Singleton
{
	public static void main(String[] args)
	{
		LogUtil.getInstance().info("test singleton design modern ");
		
		System.out.println(ConnectionManager.getInstance().getConnection());
	}
}

/**
 * 单例模式应用 之 日志工具
 * 场景分析:为了定位问题方便,每个类中都需要打印。如果每次打印日志(这里以debug级别为例)
 * 都  new Log().debug(),也就是记录一次日志 new 一个Log对象,显然浪费内存空间。这种情况就可以
 * 使用单例模式来解决。
 * 
 * 说明:生成LogUtil类的单例时 方法二比方法一更优雅,使用方法一只是为了学习一下 传说中的 双重锁定(Double-Check Locking)
 * @author Administrator
 *
 */
class LogUtil
{
	private static int debug = 0;
	private static int info = 1;
	private static int error = 2;
	private static int level = debug;//在配置文件中,值可配置
	
	private LogUtil(){}
	
	private static LogUtil logUtil = null; //方法一
	public static LogUtil getInstance()
	{
<span style="white-space:pre">		</span>// 双重锁定
		if(null == logUtil)
		{
			synchronized (LogUtil.class)
			{
				if(null == logUtil)
				{
					logUtil = new LogUtil();
				}
			}
		}
		return logUtil;
	}
	
//	private static final LogUtil logUtil = new LogUtil(); 方法二
//	public static LogUtil getInstance(){return logUtil} 
	
	public void debug(String message)
	{
		if(debug>=level)
		{
			System.out.println(message);
		}
	}
	
	public void info(String message)
	{
		if(info>=level)
		{
			System.out.println(message);
		}
	}
	
	public void error(String message)
	{
		if(error>=level)
		{
			System.out.println(message);
		}
	}
}

/**
 * 单例模式应用 之 获取数据库连接
 * @author Mr.Snail
 *
 */
class ConnectionManager
{
	private static final String USERNAME = "root";
	private static final String PASSWORD = "1989321_ivy";
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private static final String URL = "jdbc:mysql://112.74.21.122:3306/mysql";
	
	//当然一般情况,以上参数都是读取配置文件,或者是依赖注入进来的,这里以读取配件文件为例,随便复习一下
	//Properties类的操作方法
	Properties properties = new Properties();
	private static final ConnectionManager cManager = new ConnectionManager();
	private ConnectionManager()
	{
//		InputStream is = this.getClass().getResourceAsStream("./db.properties");
//		try
//		{
//			properties.load(is);
//			USERNAME = properties.getProperty("username");
//			PASSWORD = properties.getProperty("password");
//			DRIVER = properties.getProperty("driver");
//			URL = properties.getProperty("url");
//		}
//		catch (IOException e)
//		{
//			LogUtil.getInstance().error(e.toString());
//		}
	}
	
	public static ConnectionManager getInstance(){return cManager;}
	
	/**
	 * 获取数据库连接
	 * @return Connection
	 */
	public Connection getConnection()
	{
		Connection conn = null;
		try
		{
			Class.forName(DRIVER);
			conn =  DriverManager.getConnection(URL, USERNAME, PASSWORD);
		} 
		catch (ClassNotFoundException e)
		{
			LogUtil.getInstance().error(e.toString());
			throw new RuntimeException(e.toString());
		}
		catch (SQLException e)
		{
			LogUtil.getInstance().error(e.toString());
			throw new RuntimeException(e.toString());
		}
		return conn;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值