设计模式之单例设计模式
admin
2023-03-15 22:21:15
0

SINGLETON(单件)—对象创建型模式

1. 意图

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

2. 动机

    对一些类来说,只有一个实例是很重要的。虽然系统中可以有许多打印机,但却只应该有一个打印假脱机(printer spooler),只应该有一个文件系统和一个窗口管理器。一个数字滤波器只能有一个A / D转换器。一个会计系统只能专用于一个公司。

    我们怎么样才能保证一个类只有一个实例并且这个实例易于被访问呢?一个全局变量使得一个对象可以被访问,但它不能防止你实例化多个对象。一个更好的办法是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建(通过截取创建新对象的请求),并且它可以提供一个访问该实例的方法。这就是S i n g l e t o n模式。

3. 适用性

    在下面的情况下可以使用S i n g l e t o n模式

当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

适用场景:

    将来系统是高并发的,比如dbinfo,数据库信息放在配置文件里面,高并发作用是只读取一次配置文件。

    dbinfo

    servlet

    监听器

    过滤器

注:request和response不是单例对象。每个人访问的都是同一个servlet,但是不同在于,每个人的请求request是不同的,request对象是servlet容器创建的。request对象跟HTTP请求绑定在一起的,一个HTTP请求绑定一个request。

application是一个全局变量,也是一个单例对象。

4. 结构

设计模式之单例设计模式

5. 参与者

S i n g l e t o n

— 定义一个 I n s t a n c e操作,允许客户访问它的唯一实例。 I n s t a n c e是一个类操作(即

S m a l l t a l k中的一个类方法和C + +中的一个静态成员函数)。

— 可能负责创建它自己的唯一实例。

6. 协作

客户只能通过S i n g l e t o n的I n s t a n c e操作访问一个S i n g l e t o n的实例。

7.实现

常见单例的两种写法:

写法一:

public class ConnectionFactory {
	
	private static ConnectionFactory factory;                    //单例对象
	private DbInfo dbinfo;
	
	private ConnectionFactory(DbInfo dbinfo){
			this.dbinfo = dbinfo;	
	}
	
	public static ConnectionFactory instance(){
		if(factory == null){	
			DbInfo dbinfo = DbInfo.instance();
			factory = new ConnectionFactory(dbinfo);			
		}
		return factory;
	}
	
	/**
	 * 打开一个数据库连接
	 * @return
	 */
	public DbConnection openConnection(){
		DbConnection connection;
		if(this.dbinfo.getDriver().equals("oracle")){
			connection = new OracleConnection(factory);
		}else{
			connection = new MysqlConnection(factory);
		}
		
		return connection;
	}	
	
}

写法二:

public class ConnectionFactory2 {
	
	private static ConnectionFactory2 factory;              //1.要有单例对象
	
	private ConnectionFactory2(){
		
	}
	
	static{
		
		factory = new ConnectionFactory2();
		
	}
	
	public static DbConnection openConnection(){
		
		DbConnection connection;
		
		DbInfo dbinfo = DbInfo.instance();
		if(dbinfo.getDriver().equals("oracle")){
			connection = new OracleConnection(factory);
		}else{
			connection = new MysqlConnection(factory);
		}
		
		return connection;		
		
	}
}


线程相关单例写法:

//饿汉式。(常用)

class Single
{
    private static final Single s = new Single();
    private Single(){}
    public static Single getInstance()
    {
        return s;
    }
}

//懒汉式(延迟加载单例设计模式)

class Single{
    private static Single s = null;
    private Single(){}
    public static  Single getInstance(){
        if(s==null){       //多重判断
            synchronized(Single.class){     //注意锁的用法
                if(s==null)
                    s = new Single();
            }
        }
        return s;
    }
}

单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。


8.将数据库配置文件(文件配置,xml配置)内容解析到单例对象中

01.解析配置文件

    配置文件

dbURL=jdbc:oracle:thin:@10.0.19.252:1521:orcl
dbDriver=oracle.jdbc.driver.OracleDriver
username=moto
password=123456

    单例类

public class DbInfo {
	private static DbInfo dbInfo;                      //单例对象
	private String dbURL;
	private String dbDriver;
	private String username;
	private String password;
	
	private DbInfo(){
		
	}
	
	public static DbInfo instance() throws Exception{
		if(dbInfo == null){
			dbInfo = new DbInfo();
			dbInfo.init();
		}	
		
		return dbInfo;
	}
	
	/**
	 * 读取配置文件,给属性初始化
	 */
	private void init() throws Exception {
		Properties prop = new Properties();
		String path = DbInfo.class.getResource("/").getPath() + "db.properties";
		prop.load(new FileInputStream(new File(path)));
		this.dbDriver = prop.getProperty("dbDriver");
		this.dbURL = prop.getProperty("dbURL");
		this.password = prop.getProperty("password");
		this.username = prop.getProperty("username");
	}

	public String getDbURL() {
		return dbURL;
	}	

	public String getDbDriver() {
		return dbDriver;
	}
	
	public String getUsername() {
		return username;
	}	

	public String getPassword() {
		return password;
	}

}

02.解析xml文件

    xml文件





   jdbc:oracle:thin:@10.0.19.252:1521:orcl
   oracle.jdbc.driver.OracleDriver
   moto
   123456



       

    单例类

public class DbInfo2 {
	
	private static DbInfo2 dbInfo;                      //单例对象
	private String dbURL;
	private String dbDriver;
	private String username;
	private String password;
	private Document document;
	
	private DbInfo2(){
		
	}
	
	public static DbInfo2 instance() throws Exception{
		if(dbInfo == null){
			dbInfo = new DbInfo2();
			dbInfo.init();
		}	
		
		return dbInfo;
	}
	
	/**
	 * 读取配置文件,给属性初始化
	 */
	private void init() throws Exception {
		
		String path = DbInfo.class.getResource("/").getPath() + "config.xml";
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		document = db.parse(new File(path));								//解析XML文件	
		Node node = document.getElementsByTagName("DbInfo").item(0);
		Element element = (Element)node;
		dbURL = element.getAttribute("dbUrl");
		dbDriver = element.getAttribute("dbDriver");
		this.username = element.getAttribute("username");
		this.password = element.getAttribute("password");
	}

	public String getDbURL() {		
		return dbURL;
	}	

	public String getDbDriver() {
		return dbDriver;
	}
	
	public String getUsername() {
		return username;
	}	

	public String getPassword() {
		return password;
	}


}
/**
* 读取配置文件,给属性初始化
*/
//解析
//
private void init() throws Exception {
		
	String path = DbInfo.class.getResource("/").getPath() + "config.xml";
	DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	DocumentBuilder db = dbf.newDocumentBuilder();
	document = db.parse(new File(path));								//解析XML文件	
	Node node = document.getElementsByTagName("DbInfo").item(0);
	Element element = (Element)node;
	dbURL = element.getAttribute("dbUrl");
	dbDriver = element.getAttribute("dbDriver");
	this.username = element.getAttribute("username");
	this.password = element.getAttribute("password");
}

相关内容

热门资讯

ICC逮捕令致内塔尼亚胡出行受... 【环球网报道】据以色列《新消息报》网站26日报道,由于国际刑事法院(ICC)2024年就以色列在巴勒...
“罗永浩怒斥电视机厂商”戳中了... 7月25日晚,罗永浩发文怒斥当下电视机的产品设计。据都市快报报道,罗永浩表示,他为家中老人换了两次电...
各地各部门坚持人民至上筑牢防汛... 新华社北京7月25日电 题:风雨同舟映初心——各地各部门坚持人民至上筑牢防汛抗洪坚实堤坝新华社记者当...
法院回应LV起诉地产开发商 7月26日,厦门市湖里区人民法院发布情况通报,网传案情“路易威登公司起诉地产开发商,因楼盘外立面四叶...
携程的问题不仅在于垄断,更在于... 国内平台科技企业一般都是通过向B端收费、抽佣获利,尽量给消费者创造一个比较清爽的使用环境。携程算是最...
海信电视用遥控器关闭后打不开 原因可能是遥控器的电池没有装好或者是没电了,需要重新安装一下电池或者更换新的电池试一试;原因可能是电...
电视机突然没电源打不开了 有可能是电视开关的电源线断了;可能是电视在使用时短路;可能是电源插头插座松动;可能是电视内部零件接触...
电热水器下面那个小龙头漏水是怎... 电热水器下面那个小龙头漏水是怎么回事?1、因为安全阀发生了故障或者是已经被损坏了,就会有漏水的现象;...
回答下电脑桌面一片空白怎么恢复 电脑桌面上如果是一片空白,那说明您的电脑图标被隐藏了,想要恢复就要按照如下的三个步骤去操作才行。 第...
澳总理要找特朗普“理论”关税:... 当地时间7月26日,澳大利亚总理阿尔巴尼斯表示,他将直接向美国总统特朗普提出抗议,反对美国新近宣布的...