目錄
- 前言
- 設計模式(design pattern)?
- 設計模式分類:
- 一、創建型模式
- 二 、結構型模式
- 三、行為型模式
- Singleton Pattern(單例模式)?
- 餓漢式
- 懶漢式
- 雙重判斷
- 靜態內部類
- 列舉式
前言
在我們平時的作業學習中,代碼的整潔與高可用會讓程式更加有效率,對專案的好處不言而喻,
設計模式的學習會讓我們的編程水平得到很大的提升,同時也有助于對框架的理解,因為優秀的框架結構都用到了設計模式,
今天先瞅瞅單例模式,剩余的設計模式我也會慢慢更新,做一個系列,
設計模式(design pattern)?
設計模式,是一套被反復使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結, 是對面向物件設計中反復出現的問題的解決方案
使用設計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程式的重用性,
Java設計模式貫徹的原理是:面向介面編程,而不是面向實作,其目標的原則是:降低耦合,增強靈活性,
設計模式分類:
一、創建型模式
創建型模式是用來創建物件的模式,抽象了實體化的程序,幫助一個系統獨立于其關聯物件的創建、組合和表示方式,
所有的創建型模式都有兩個主要功能:
- 將系統所使用的具體類資訊封裝起來;
- 隱藏類的實體是如何被創建和組織的,外界對于這些物件只知道他們共同的介面,而不清楚其具體的實作細節,
常見的創建型模式:
- 單例模式(Singleton Pattern)
- 工廠方法模式(Factory Pattern)
- 抽象工廠模式(Abstract Factory Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype pattern)
二 、結構型模式
結構型模式討論的是類和物件的結構,它采用繼承機制來組合介面或實作(類結構型模式),或者通過組合一些物件實作新的功能(物件結構型模式),
常見結構型模式:
- 代理模式(Proxy)
- 裝飾模式(Decorator)
- 配接器模式(Adapter)
- 組合模式(Composite)
- 橋梁模式(Bridge)
- 外觀模式(Facade)
- 享元模式(Flyweight)
三、行為型模式
行為型模式關注的是物件的行為,用來解決物件之間的聯系問題,
常見行為型模式:
- 模板方法模式(Template Method)
- 命令模式(Commend)
- 責任鏈模式(Chain of Responsibility)
- 策略模式(Strategy)
- 迭代器模式(Iterator)
- 中介者模式(Mediator)
- 觀察者模式(Observer)
- 備忘錄模式(Memento)
- 訪問者模式(Visitor)
- 狀態模式(State)
- 解釋器模式(Interpreter)
Singleton Pattern(單例模式)?
定義:Ensure a class has only one instance, and provide a global Point of access to it.
確保一個類只有一個實體存在,
最好學習方法就是分析代碼:
餓漢式
/**
* 餓漢式(類加載時,就進行物件實體化)
* 類加載到記憶體后,就實體化一個單例,JVM保證執行緒安全
* 類只加載一次,實體化一次 Class.forName()
* 缺點:類完成加載,就完成實體化
*/
public class Manager01 {
//private確保構造方法無法被外界實體化
private Manager01(){
}
//靜態常量(或變數)
private static final Manager01 INSTANCE = new Manager01();
//通過該方法獲得實體
public static Manager01 getInstance(){
return INSTANCE;
}
//其余業務方法
public void useOthers(){
}
public static void main(String[] args) {
Manager01 instance1 = Manager01.getInstance();
Manager01 instance2 = Manager01.getInstance();
//輸出結果為True,同一個物件
System.out.println(instance1==instance2);
}
}
懶漢式
/**
* 懶漢式(第一次參考類時,才進行物件實體化)
* Lazy Loading
* 按需初始化,但要保證多執行緒并發安全
*/
public class Manager02 {
private Manager02(){}
private static Manager02 INSTANCE;
public static Manager02 getInstance(){
//public static synchronized Manager02 getInstance()
//加鎖亦可在方法上,保證同步,多執行緒容易發生創建多個實體
synchronized (Manager02.class){
//判斷是否已實體化
if (INSTANCE==null){
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Manager02();
}
return INSTANCE;
}
}
//業務方法等
public void useOthers(){}
public static void main(String[] args) {
//創建100個執行緒,結果只有一個實體被創建
for (int i = 0; i < 100; i++) {
//lambda運算式
new Thread(()->{
System.out.println(Manager02.getInstance().hashCode());
}).start();
}
}
}
雙重判斷
懶漢式模式會加鎖,導致效率降低,雙重模式是對懶漢的優化
/**
* 雙重判斷
*/
public class Manager03 {
private Manager03(){}
private static Manager03 instance;
public static Manager03 getInstance(){
//判斷第一次,若實體已存在,直接跳轉回傳instance,無需等待鎖的釋放
if (instance==null){
synchronized (Manager03.class){
//二次判斷,若此時已存在實體,就跳過if塊
if (instance==null){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Manager03();
return instance;
}
}
}
return instance;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager03.getInstance().hashCode());
}).start();
}
}
}
靜態內部類
/**
* 靜態內部類
* 加載外部類時不會加載內部類,懶加載
*/
public class Manager04 {
private Manager04(){}
private static class managerHolder {
private final static Manager04 INSTANCE = new Manager04();
}
public static Manager04 getInstance(){
return managerHolder.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager04.getInstance().hashCode());
}).start();
}
}
}
列舉式
/**
* 列舉單例
* 大佬寫的,不僅解決執行緒同步,還可以反序列化
* 完美
*/
public enum Manager05 {
INSTANCE;
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Thread(()->{
System.out.println(Manager05.INSTANCE.hashCode());
}).start();
}
}
}
最常用最簡單的就是餓漢式,懶漢式了,
上面示例為看視頻總結手敲,很精妙
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/277322.html
標籤:java
上一篇:從JVM的視角深度決議String和StringBuilder的區別
下一篇:java生成隨機字串的兩種方法
