溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

設(shè)計(jì)模式之單例設(shè)計(jì)模式

發(fā)布時(shí)間:2020-06-06 13:21:30 來源:網(wǎng)絡(luò) 閱讀:688 作者:叫我北北 欄目:建站服務(wù)器

SINGLETON(單件)—對(duì)象創(chuàng)建型模式

1. 意圖

    保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。

2. 動(dòng)機(jī)

    對(duì)一些類來說,只有一個(gè)實(shí)例是很重要的。雖然系統(tǒng)中可以有許多打印機(jī),但卻只應(yīng)該有一個(gè)打印假脫機(jī)(printer spooler),只應(yīng)該有一個(gè)文件系統(tǒng)和一個(gè)窗口管理器。一個(gè)數(shù)字濾波器只能有一個(gè)A / D轉(zhuǎn)換器。一個(gè)會(huì)計(jì)系統(tǒng)只能專用于一個(gè)公司。

    我們?cè)趺礃硬拍鼙WC一個(gè)類只有一個(gè)實(shí)例并且這個(gè)實(shí)例易于被訪問呢?一個(gè)全局變量使得一個(gè)對(duì)象可以被訪問,但它不能防止你實(shí)例化多個(gè)對(duì)象。一個(gè)更好的辦法是,讓類自身負(fù)責(zé)保存它的唯一實(shí)例。這個(gè)類可以保證沒有其他實(shí)例可以被創(chuàng)建(通過截取創(chuàng)建新對(duì)象的請(qǐng)求),并且它可以提供一個(gè)訪問該實(shí)例的方法。這就是S i n g l e t o n模式。

3. 適用性

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

當(dāng)類只能有一個(gè)實(shí)例而且客戶可以從一個(gè)眾所周知的訪問點(diǎn)訪問它時(shí)。

當(dāng)這個(gè)唯一實(shí)例應(yīng)該是通過子類化可擴(kuò)展的,并且客戶應(yīng)該無需更改代碼就能使用一個(gè)擴(kuò)展的實(shí)例時(shí)。

適用場(chǎng)景:

    將來系統(tǒng)是高并發(fā)的,比如dbinfo,數(shù)據(jù)庫信息放在配置文件里面,高并發(fā)作用是只讀取一次配置文件。

    dbinfo

    servlet

    監(jiān)聽器

    過濾器

注:request和response不是單例對(duì)象。每個(gè)人訪問的都是同一個(gè)servlet,但是不同在于,每個(gè)人的請(qǐng)求request是不同的,request對(duì)象是servlet容器創(chuàng)建的。request對(duì)象跟HTTP請(qǐng)求綁定在一起的,一個(gè)HTTP請(qǐng)求綁定一個(gè)request。

application是一個(gè)全局變量,也是一個(gè)單例對(duì)象。

4. 結(jié)構(gòu)

設(shè)計(jì)模式之單例設(shè)計(jì)模式

5. 參與者

S i n g l e t o n

— 定義一個(gè) I n s t a n c e操作,允許客戶訪問它的唯一實(shí)例。 I n s t a n c e是一個(gè)類操作(即

S m a l l t a l k中的一個(gè)類方法和C + +中的一個(gè)靜態(tài)成員函數(shù))。

— 可能負(fù)責(zé)創(chuàng)建它自己的唯一實(shí)例。

6. 協(xié)作

客戶只能通過S i n g l e t o n的I n s t a n c e操作訪問一個(gè)S i n g l e t o n的實(shí)例。

7.實(shí)現(xiàn)

常見單例的兩種寫法:

寫法一:

public class ConnectionFactory {
	
	private static ConnectionFactory factory;                    //單例對(duì)象
	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;
	}
	
	/**
	 * 打開一個(gè)數(shù)據(jù)庫連接
	 * @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.要有單例對(duì)象
	
	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;		
		
	}
}


線程相關(guān)單例寫法:

//餓漢式。(常用)

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

//懶漢式(延遲加載單例設(shè)計(jì)模式)

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;
    }
}

單例模式有以下特點(diǎn):
1、單例類只能有一個(gè)實(shí)例。
2、單例類必須自己創(chuàng)建自己的唯一實(shí)例。
3、單例類必須給所有其他對(duì)象提供這一實(shí)例。


8.將數(shù)據(jù)庫配置文件(文件配置,xml配置)內(nèi)容解析到單例對(duì)象中

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;                      //單例對(duì)象
	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文件

<?xml version="1.0" encoding="UTF-8"?>
<config>

<dbinfo>
   <dbUrl>jdbc:oracle:thin:@10.0.19.252:1521:orcl</dbUrl>
   <dbDriver>oracle.jdbc.driver.OracleDriver</dbDriver>
   <username>moto</username>
   <password>123456</password>
</dbinfo>

<DbInfo dbUrl="jdbc:oracle:thin:@10.0.19.252:1521:orcl"  dbDriver="oracle.jdbc.driver.OracleDriver"
       username="moto" password="123456"></DbInfo>
       
</config>

    單例類

public class DbInfo2 {
	
	private static DbInfo2 dbInfo;                      //單例對(duì)象
	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;
	}


}
/**
* 讀取配置文件,給屬性初始化
*/
//解析
//<DbInfo dbUrl="jdbc:oracle:thin:@10.0.19.252:1521:orcl"  dbDriver="oracle.jdbc.driver.OracleDriver"
//       username="moto" password="123456"></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");
}
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI