prototype 原型模式:(實際也叫轉殖模式)用乙個已經建立的例項作為原型,通過複製該原型物件來建立乙個和原型相同或相似的新物件。在這裡,原型例項指定了要建立的物件的種類。用這種方式建立物件非常高效,根本無須知道物件建立的細節原型模式的優點:結構圖:
例項:建立乙個person物件, 通過原型模式轉殖乙份(實際就是呼叫object的clone方法)
實現需要兩個步驟:
1、實現clonable介面,這個介面雖然沒有任何方法,只是乙個標記,但是必須實現它,否則執行出錯(編譯不會出錯)
2、呼叫object父類的clone方法(看原始碼可以看出,clone方法是native方法,實際底層用的c++實現的。就是直接從記憶體copy乙份)
public
class
prototype
}class
person
implements
cloneable
@override
public object clone()
throws clonenotsupportedexception
}class
bird
}
列印值:
// 可以看出轉殖出來後,兩個物件一模一樣
張三--------張三
12--------12
小鳥-------小鳥
2-------2
分割線--------------------------------
// 改變p屬性的值後,看看兩個物件的值得變化
李四--------張三
10--------12
大鳥-------大鳥 // 這裡我只是改變了 p 物件的值,為什麼 p2 的值也跟著變了?
3-------3
通過上面可以看出乙個問題,基本變數通過clone方法可以完全轉殖乙份,互相沒有牽扯但是引用物件的值還是一模一樣的(這是因為bird只是個引用,轉殖乙份,bird物件還是同乙個)
看圖:這裡就牽扯出乙個概念:淺轉殖,深轉殖
淺轉殖
只會轉殖基本型別,對引用型別是轉殖不了的。
(有些人可能會問string不是基本型別,string也是個物件型別,他也是乙個引用。string比較特殊,雖然是個引用型別,但是他指向乙個常量池。當你改變string的引用的時候,另乙個引用不會變。看下圖)
深轉殖
無論基本型別還是引用型別都需要轉殖乙份
注:如果要完成深轉殖就需要把需要轉殖的引用物件也按照person類的形式做一遍,實現clonable介面,重寫clone方法。
深刻了例項:
public
class
prototype
}class
person
implements
cloneable
@override
public object clone()
throws clonenotsupportedexception
}class
bird
implements
cloneable
@override
public object clone()
throws clonenotsupportedexception
}
執行結果:
張三--------張三
12--------12
小鳥-------小鳥
2-------2
分割線-------------------------------- // 看下面,p物件的更改,完全影響不到p2物件了。實現了深轉殖
李四--------張三
10--------12
大鳥-------小鳥
3-------2
總結:從上面可以看出,如果轉殖帶有引用的物件,寫起來是比較麻煩的。特別是屬性引用多的,每個引用物件都要實現一遍cloneable介面,重寫一下clone方法,主類的clone方法也要手動賦值,挺麻煩的。淺轉殖還是比較好用的。 二十三種設計模式之組合模式
組合模式 將物件聚合成樹形結構來表現 整體 部分 的層次結構。組合模式能讓客戶以一致的方式來處理個別物件以及物件組合。也就是我們可以忽略物件組合與個體之間的差別。應用場景 餐廳合併列印主選單 子選單 public abstract class menucomponent public string ...
二十三種設計模式之工廠模式
工廠模式的核心 例項化物件 原因 有些物件不能直接例項化,比如介面 抽象類及複雜物件的其他依賴 核心 呼叫工廠class的靜態方法例項化物件 以日誌為例 public class staticfactory 核心 先建立工廠物件,之後呼叫工廠方法 例項化工廠模式 public class insta...
二十三種設計模式之模板設計模式
按照我的理解來說,就是乙個流程中,總體的步驟是固定的,但有些步驟是改變的,例如我們做煎蛋這個過程,有哪些步驟是固定的呢,打蛋,下鍋,上碟都是固定的,但有時候我們想吃鹹的,有時候想吃甜的,所以在說放佐料的步驟是改變的。所有的設計模式都是把變化點和固定點分離開來,所謂的固定和變化是相對的,例如我們有乙個...