java設計模式總結(二) ---- 五中建立型模式(引用一下韓老師的程式碼)
設計模式的分類
總體來說設計模式分為三大類:
建立型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。
結構型模式,共七種:介面卡模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。
行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代子模式、責任鏈模式、命令模式、備忘錄模式、狀態模式、訪問者模式、中介者模式、直譯器模式。
https://www.cnblogs.com/fswhq/p/sjms.html
建立模式(5種)
工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式
1,單例設計模式
定義:確保一個類最多隻有一個例項,並提供一個全域性訪問點
八種方式:
1> 餓漢式(靜態常量)
2> 餓漢式(靜態程式碼塊)
3> 懶漢式(執行緒不安全)
4> 懶漢式(同步方法)
5> 懶漢式(同步程式碼塊)
6> 雙重檢查
7> 靜態內部類
8> 列舉
1.1餓漢式(靜態常量)
class Singleton { //1. 構造器私有化, 外部能new private Singleton() { } //2.本類內部建立物件例項 private final static Singleton instance = new Singleton();//3. 提供一個公有的靜態方法,返回例項物件 public static Singleton getInstance() { return instance; } }
優點:簡單,沒有執行緒安全問題
缺點:老友Lazy Loading效果,沒有使用該單例時,浪費記憶體
1.2餓漢式(靜態程式碼塊)
class Singleton { //1. 構造器私有化, 外部能new private Singleton() { } //2.本類內部建立物件例項 private staticSingleton instance; static { // 在靜態程式碼塊中,建立單例物件 instance = new Singleton(); } //3. 提供一個公有的靜態方法,返回例項物件 public static Singleton getInstance() { return instance; } }
優缺點和上面一種餓漢式差不多
1.3懶漢式(執行緒不安全)
class Singleton { private static Singleton instance; private Singleton() {} //提供一個靜態的公有方法,當使用到該方法時,才去建立 instance //即懶漢式 public static Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } }
優缺點:
有Lazy Loading的效果,只能在單執行緒下使用
多執行緒下會出現多個例項
不要使用這種方式
class Singleton { private static Singleton instance; private Singleton() {} //提供一個靜態的公有方法,加入同步處理的程式碼,解決執行緒安全問題 //即懶漢式 public static synchronized Singleton getInstance() { if(instance == null) { instance = new Singleton(); } return instance; } }
優缺點:沒有執行緒安全問題
效率太低,每次都要進去都要同步
1.5懶漢式(執行緒安全,同步程式碼塊)
// 懶漢式(執行緒安全,同步方法) class Singleton { private static Singleton instance; private Singleton() {} //提供一個靜態的公有方法,加入同步處理的程式碼,解決執行緒安全問題 //即懶漢式 public static Singleton getInstance() { if(instance == null) { synchronized(Singleton.class){ instance = new Singleton(); } } return instance; } }
多執行緒時會產生多例
1.6 雙重檢查
class Singleton { private static volatile Singleton instance; private Singleton() {} //提供一個靜態的公有方法,加入雙重檢查程式碼,解決執行緒安全問題, 同時解決懶載入問題 //同時保證了效率, 推薦使用 public static synchronized Singleton getInstance() { if(instance == null) { synchronized (Singleton.class) { if(instance == null) { instance = new Singleton(); } } } return instance; } }
優缺點:執行緒安全;延遲載入;效率高
1.7 靜態內部類
// 靜態內部類完成, 推薦使用 class Singleton { private static volatile Singleton instance; //構造器私有化 private Singleton() {} //寫一個靜態內部類,該類中有一個靜態屬性 Singleton private static class SingletonInstance { private static final Singleton INSTANCE = new Singleton(); } //提供一個靜態的公有方法,直接返回SingletonInstance.INSTANCE public static synchronized Singleton getInstance() { return SingletonInstance.INSTANCE; } }
優缺點:使用類載入機制;使用時在例項化;第一次載入時才初始化jvm保證單例
1.8 列舉
//使用列舉,可以實現單例, 推薦 enum Singleton { INSTANCE; //屬性 }
JDK5.0新特性,還防止了序列化
1.9單例模式在JDK中的使用
使用的餓漢式
1.10細節說明和使用事項
1 工廠模式(包括簡單工廠,工廠方法,抽象工廠)
1.1 簡單工廠模式
定義:定義了一個建立物件的類,由這個類來封裝例項化物件的行為。
舉例:(我們舉一個pizza工廠的例子)
使用簡單工廠:
public Pizza createPizza(String orderType) { Pizza pizza = null; System.out.println("使用簡單工廠模式"); if (orderType.equals("greek")) { pizza = new GreekPizza(); pizza.setName(" 希臘披薩 "); } else if (orderType.equals("cheese")) { pizza = new CheesePizza(); pizza.setName(" 乳酪披薩 "); } else if (orderType.equals("pepper")) { pizza = new PepperPizza(); pizza.setName("胡椒披薩"); } return pizza; }
1.2 工廠方法模式
定義:定義了一個建立物件的抽象方法,由子類決定要例項化的類。工廠方法模式將物件的例項化推遲到子類。
舉例:(我們依然舉pizza工廠的例子,不過這個例子中,pizza產地有兩個:倫敦和紐約)。添加了一個新的產地,如果用簡單工廠模式的的話,我們要去修改工廠程式碼,並且會增加一堆的if else語句。而工廠方法模式克服了簡單工廠要修改程式碼的缺點,它會直接建立兩個工廠,紐約工廠和倫敦工廠。類圖如下:
在簡單工廠的基礎上增加了多個工廠,就讓一個父類工廠去管理
子類的主要程式碼和簡答工廠差不多
public class BJOrderPizza extends OrderPizza { @Override Pizza createPizza(String orderType) { Pizza pizza = null; if(orderType.equals("cheese")) { pizza = new BJCheesePizza(); } else if (orderType.equals("pepper")) { pizza = new BJPepperPizza(); } // TODO Auto-generated method stub return pizza; } }
1.3 抽象工廠模式
定義:定義了一個介面用於建立相關或有依賴關係的物件族,而無需明確指定具體類。
舉例:(我們依然舉pizza工廠的例子,pizza工廠有兩個:紐約工廠和倫敦工廠)。類圖如下:
//一個抽象工廠模式的抽象層(介面) public interface AbsFactory { //讓下面的工廠子類來 具體實現 public Pizza createPizza(String orderType); }
把工廠方法模式加到介面之中,區別感覺不大
1.4工廠在JDK中的使用
在Calader中使用了簡單工廠模式,根據時區來建立相應的子類物件
總結:工廠的好處,在建立的物件的時候我們會有各種各樣的要求,我們把這一部分都講給工廠去處理。我們在使用的時候只需要用方法區獲取到類就行。不程式碼分離開
簡單工廠:根據條件new
工廠方法:用父類來管理相似的工廠類
抽象工廠模式:用介面來管理相關的工廠類
ps:該模式是違反ocp原則的,對於新類工廠無法進行擴充套件。因為要去改工廠原本的方法
3原型模式
原型模式就是對一個類進行復制,在Cloneable介面中已經實現了,我們重寫一下就行
@Override protected Object clone() { Sheep sheep = null; try { sheep = (Sheep)super.clone(); } catch (Exception e) { // TODO: handle exception System.out.println(e.getMessage()); } // TODO Auto-generated method stub return sheep; }
深拷貝和淺拷貝:如果我們在clone方法中,拷貝對於類中以其他類作為屬性時,我們把他指向同一個物件,這樣複製出來的過程叫淺拷貝,否則,就是深拷貝。如下圖
淺拷貝:
我們的類屬性:
重寫clone:
客戶端複製:
執行結果:
上圖就是淺拷貝。
下面是深拷貝,有兩種方式,方式一在複製屬性物件時我們把該物件裡面的clone也重新並且呼叫:
public String name; //String 屬性 public DeepCloneableTarget deepCloneableTarget;// 引用型別 public DeepProtoType() { super(); } //深拷貝 - 方式 1 使用clone 方法 @Override protected Object clone() throws CloneNotSupportedException { Object deep = null; //這裡完成對基本資料型別(屬性)和String的克隆 deep = super.clone(); //對引用型別的屬性,進行單獨處理 DeepProtoType deepProtoType = (DeepProtoType)deep; deepProtoType.deepCloneableTarget = (DeepCloneableTarget)deepCloneableTarget.clone(); // TODO Auto-generated method stub return deepProtoType; }
方式二,進行序列化,再進行反序列化:
public String name; //String 屬性 public DeepCloneableTarget deepCloneableTarget;// 引用型別 public DeepProtoType() { super(); } public Object deepClone() { //建立流物件 ByteArrayOutputStream bos = null; ObjectOutputStream oos = null; ByteArrayInputStream bis = null; ObjectInputStream ois = null; try { //序列化 bos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(bos); oos.writeObject(this); //當前這個物件以物件流的方式輸出 //反序列化 bis = new ByteArrayInputStream(bos.toByteArray()); ois = new ObjectInputStream(bis); DeepProtoType copyObj = (DeepProtoType)ois.readObject(); return copyObj; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); return null; } finally { //關閉流 try { bos.close(); oos.close(); bis.close(); ois.close(); } catch (Exception e2) { // TODO: handle exception System.out.println(e2.getMessage()); } } }
原型設計模式在Spring bean設定當中使用了
以上就是原型模式的全部內容。
4 建造者模式(生成器模式)
作用:把一個複雜的物件,內部結構和操作分離開來。內部結構不呈現給使用者
以造房子為例,傳統方式
畫紅線處,操作在使用者用體現。
使用建造者模式:
指揮者去完成功能
在JDK--StringBuilder中的應用
好了,五中建立型模式就寫到這兒,我寫的東西不會放全部程式碼,會多給原理圖和重要程式碼截圖