//-------------------------------------------------------------餓漢模式--開始----------------------------------------------------------- package com.study.DesignPattern01; /** * 創建一個餓漢模式的單例 * @author ZLHome *有些對象,我們只需要一個,如果多了,那么就可能導致數據不一致, 占用資源過多等等,比如: 配置文件、工具類、線程池、緩存、日志對象 */ public class Singleton { //1、構造方法私有化(這樣類就不能被實例化了) private Singleton(){ System.out.println("實例化Singleton類"); } //2、實例化單例對象,對象為靜態的(這樣就只會實例化一次),私有的(安全,外部不能直接Singleton.instance調用) private static Singleton instance = new Singleton(); //3、提供一個靜態方法(靜態方法,類可以直接調用),用於獲取單例 public static Singleton getInstance(){ return instance; } } //--------------------------------------------------------------------------------------------- package com.study.DesignPattern01; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class SingletonTest { @BeforeClass public static void setUpBeforeClass() throws Exception { System.out.println("Junit開始BeforeClass..."); } @AfterClass public static void tearDownAfterClass() throws Exception { System.out.println("Junit過后AfterClass..."); } @Before public void setUp() throws Exception { System.out.println("Junit開始Before..."); } @After public void tearDown() throws Exception { System.out.println("Junit過后After..."); } @Test public void test() { System.out.println("Junit開始..."); Singleton instance = Singleton.getInstance(); Singleton instance1 = Singleton.getInstance(); System.out.println("是否相等:"+(instance==instance1)); } } //-------------------------------------------------------------餓漢模式--結束----------------------------------------------------------- //============================================================懶漢模式--開始============================================================ package com.study.DesignPattern01; public class Singleton1 { //1、將構造方法設置為私有(這樣類就不能被外部實例化了) private Singleton1(){ System.out.println("實例化Singleton1"); } //2、申明單例對象 private static Singleton1 instance; //3、提供一個靜態方法(靜態方法屬於類),用於外部調用 public static Singleton1 getInstance(){ if(instance==null){ System.out.println("第一次實例化Singleton1對象"); instance=new Singleton1(); } return instance; } } //============================================================ package com.study.DesignPattern01; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class Singleton1Test { @BeforeClass public static void setUpBeforeClass() throws Exception { System.out.println("Junit開始BeforeClass..."); } @AfterClass public static void tearDownAfterClass() throws Exception { System.out.println("Junit過后AfterClass..."); } @Before public void setUp() throws Exception { System.out.println("Junit開始Before..."); } @After public void tearDown() throws Exception { System.out.println("Junit過后After..."); } @Test public void test() { System.out.println("Junit開始..."); Singleton1 instance = Singleton1.getInstance(); Singleton1 instance1 = Singleton1.getInstance(); System.out.println("是否相等:"+(instance==instance1)); } } //============================================================懶漢模式--結束============================================================
設計模式
可靠性更高、更容易理解、擴展性更好‘更容易維護
1、單例模式:
1)單例背景、情況:
有些對象,我們只需要一個,如果多了,那么就可能導致數據不一致,
占用資源過多等等,比如:
配置文件、工具類、線程池、緩存、日志對象
2)原理:
實例化對象是通過構造方法來實現的(程序類未寫,則程序類有默認的構造方法),
單例只允許獲取一個實例,所以
餓漢模式:
類加載的時候就實例化對象(比較餓,主動實例對象)
(1)實現單例就去改寫構造方法:將構造方法改寫為私有的,改寫之后,就不能直接實例化了(不允許外部直接創建實例)
(2)創建類的唯一實例(類里面去new一個實例,且這個實例是static[變量、方法加static后就變成類所有,不是必須創建實例對象來調用],這樣就可以通過類直接調用這個實例[類名.實例變量名])
(3)為了安全,不允許外部直接訪問成員變量,所以(2)需要優化,將類的static實例變為private,變為private之后就不能直接通過"類名.實例變量名"來訪問了,所以提供類的方法get,類的get方法也需要是static才能通過"類名.方法名"調用
懶漢模式:
類加載的時候只是聲明一下,調用這個單例的時候才實例化(比較懶,不主動去實例對象)
(1)先聲明一個單例,並不實例化單例對象
(2)在get方法里面去判斷,如果沒有實例這個對象,就將單例對象實例化再返回
對比:
懶漢模式:類加載快,獲取對象慢,線程安全的
餓漢模式:類加載慢,獲取對象快,線程不安全
總結:static修飾的變量、方法數據類,可以通過類直接調用
