您好,登錄后才能下訂單哦!
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文件
<?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; //單例對象 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"); }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。