Python+Appium自動化測試(16)-日誌採集(詳細)
這節講一下原型模式,原型模式用於解決大量相同或相似物件的建立問題,傳統的,我們例項化物件要用new關鍵字,在面對大量重複物件的建立情況下,new例項的過程是比較消耗資源的,所以我們可以利用一個物件作為原型,通過這個物件的不斷克隆自己來產出一個個新例項(這跟js的原型物件並不相同,讀者不要跟其做理論比較)。
我們可以設想一下,為何克隆比new例項要高效:拿畫畫來說,new例項相當於每次要構思這幅畫,並將其畫出來,克隆相當於第一次構思並畫出後,後續的畫都是臨摹,所以克隆是高效的。
我們看一下原型模式的定義:用一個已經建立的例項作為原型,通過複製該原型物件來建立一個和原型相同或相似的新物件。在這裡,原型例項指定了要建立的物件的種類。用這種方式建立物件非常高效,根本無須知道物件建立的細節。
在示例程式碼之前,先要理解一個概念:深拷貝和淺拷貝:
所謂淺拷貝就是指拷貝時只拷貝值型別的屬性,引用型別的屬性地址跟原型物件的地址指向一致,而深拷貝就是將原型物件的值型別和引用型別的屬性都拷貝一份,可以說是和原型物件完全分離開來。
接下來我們看一下如何讓一個物件可被克隆:
class prototypeClass : ICloneable { public prototypeClass(string classname) { this.classname = classname; } public object Clone() {return MemberwiseClone(); } public string classname { get; set; } public void ShowName() { Console.WriteLine(classname); } }
具體的邏輯就是讓原型類實現ICloneable介面,實現介面的Clone()方法,方法中呼叫MemberwiseClone()返回一個基於該原型物件淺拷貝的物件。
在主方法中呼叫,我們檢視一下執行結果:
prototypeClass p = new prototypeClass("小明"); prototypeClass p_clone = (prototypeClass)p.Clone(); p.ShowName(); p_clone.ShowName(); Console.WriteLine(p == p_clone);
下面我再新增一個類,並在prototypeClass類中新增這個類作為屬性:
在主方法中比較一下克隆物件的s屬性是否與原型物件的s屬性相等:
執行結果如下:
結果為true,這就證明了此為淺拷貝。
若要實現深拷貝,需做點改動:
static prototypeClassS ps=new prototypeClassS("小艾"); public object Clone() { prototypeClass p=(prototypeClass) MemberwiseClone(); p.s=(prototypeClassS)ps.Clone();//手動呼叫屬性的克隆方法實現深度拷貝 return p; }
加入一個靜態原型屬性,每次克隆該原型物件時都去手動將引用物件克隆出來並賦值,如果被拷貝的屬性自己也有引用型別的屬性,為了實現深拷貝,也得做對應的修改,這樣就形成了一個拷貝鏈,層層深入,從而完成深度拷貝(其實這挺繁瑣的)。
下面我通過程式碼來演示一下new例項和克隆的效能差距:
Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int i = 0; i < 100000; i++) { prototypeClass clone = (prototypeClass)p.Clone(); } stopwatch.Stop(); Console.WriteLine("克隆時間:" + stopwatch.Elapsed); stopwatch.Start(); for (int i = 0; i < 100000; i++) { prototypeClass clone = new prototypeClass("小明",new prototypeClassS("新二")); } stopwatch.Stop(); Console.WriteLine("new 例項:" + stopwatch.Elapsed);
在主方法中編寫上述程式碼,下面看一下執行結果:
差距不言而喻。
當然,原型模式也有缺點:
-
我們需要為每一個類都配置一個clone方法,clone方法位於類的內部,當對已有類進行改造的時候,需要修改程式碼,違背了開閉原則。
-
當實現深克隆時,需要編寫較為複雜的程式碼,而且當物件之間存在多重巢狀引用時,為了實現深克隆,每一層物件對應的類都必須支援深克隆,實現起來會比較麻煩。
個人公眾號,熱愛分享,知識無價。