您好,登錄后才能下訂單哦!
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)
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"); }
免責(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)容。