系統設計之緩存五種策略 當我們在架構中引入緩存時,緩存和資料庫之間的同步就變得不可避免。 讓我們看看如何保持數據同步的五種常見策略。 1)閱讀策略: 緩存在一邊 通讀2)寫策略:寫周圍 回信 寫通緩存策略經常組合使用。例如,write-around 通常與 cache-aside 一起使用,以確保緩 ...
1 模式的定義
原型模式(Prototype Pattern)是一種創建型設計模式,其主要目的是通過複製現有對象來創建新對象,而不是使用構造函數。原型模式將對象的創建委托給原型對象,通過克隆(複製)來生成新對象,這種方式可以避免對象的重覆初始化,提高性能,並使對象的創建更加靈活和動態。
原型模式的關鍵思想是通過複製已有對象的屬性和狀態來創建新的對象,這種方式避免了每次都使用構造函數初始化對象,特別適用於對象創建過程複雜、耗時或需要動態配置的情況。
2 舉例說明
原型模式在日常生活中的一個常見示例是使用複印機來複制文件或文檔。如果你需要複製一份文件,一般情況下不會手工重新編寫該文件的每個字,而是使用複印機來製作副本。在這裡,原文件充當原型,而複印機則是用於創建新文件副本的工具。使用複印機來複制文件,通過克隆原文件來創建新文件副本,從而節省時間和工作量。
還有一個例子就是在西游記中,孫悟空用自己的猴毛變成很多新的孫悟空,也可以看作孫悟空用自己做原型,拷貝出相同的猴子。
這些例子都有助於更好地理解原型模式的概念和應用。
3 結構
原型模式的結構包括以下要素:
抽象原型介面(Prototype):這是一個抽象介面或抽象類,它聲明瞭一個克隆方法(通常命名為 clone() 或類似的名稱)。這個方法用於複製當前對象並返回一個新的副本。所有具體原型類都必須實現這個介面或繼承這個抽象類,以確保它們能夠被克隆。
具體原型類(Concrete Prototype):這些是實際的對象類,它們實現了抽象原型介面,並提供了自己的克隆方法。具體原型類通常包含對象的屬性和方法。當客戶端需要創建新對象時,它們通過調用克隆方法來複制現有對象。
客戶端(Client):客戶端代碼是使用原型模式的地方,它通過調用具體原型類的克隆方法來創建新對象。客戶端不需要瞭解對象的具體構造方式,只需知道如何複製對象。
以下是原型模式的典型結構示意圖
在這個結構中,抽象原型介面定義了克隆方法,具體原型類實現了克隆方法,並可以包含其他屬性和方法。客戶端代碼通過克隆方法創建新對象,而不必關心對象的具體構造細節。這種結構使得對象的創建更加靈活和可維護。
4 實現步驟
實現原型模式的關鍵步驟包括以下幾個:
創建抽象原型介面(Prototype):首先,創建一個抽象原型介面或抽象類,其中包含一個克隆方法(通常命名為 clone() 或類似的名稱),用於複製當前對象並返回一個新的副本。這個介面將規範所有具體原型類必須實現的方法。
創建具體原型類(Concrete Prototype):對於每個需要被克隆的具體對象類型,創建一個具體原型類,它實現了抽象原型介面,並提供了自己的克隆方法。在克隆方法中,通常會創建一個新的對象,將當前對象的屬性值複製給新對象,並返回新對象。
客戶端使用原型對象:在客戶端代碼中,當需要創建新對象時,不直接使用構造函數,而是通過克隆已有的原型對象來創建新對象。客戶端代碼通常只需要知道如何調用原型對象的克隆方法,而無需瞭解對象的具體構造細節。
克隆方法的實現:在具體原型類中,克隆方法的具體實現取決於對象的類型和屬性。如果對象包含引用類型的成員變數,需要考慮深度克隆以確保對象的所有狀態都被正確複製。
測試和驗證:在客戶端代碼中測試原型模式,確保克隆的對象與原始對象在屬性和行為上一致。
5 代碼實現
以下是一個通用的原型模式實現步驟示例(使用Java):
// 1. 創建抽象原型介面
interface Prototype {
Prototype clone();
}
// 2. 創建具體原型類
class ConcretePrototype implements Prototype {
private String field;
public ConcretePrototype(String field) {
this.field = field;
}
@Override
public Prototype clone() {
return new ConcretePrototype(this.field);
}
public void setField(String field) {
this.field = field;
}
public String getField() {
return field;
}
}
// 3. 客戶端使用原型對象
public class Client {
public static void main(String[] args) {
// 創建原型對象
Prototype original = new ConcretePrototype("Original Field");
// 克隆原型對象來創建新對象
Prototype clone = original.clone();
// 驗證新對象的屬性與原始對象相同
System.out.println("Original Field: " + original.getField());
System.out.println("Clone Field: " + clone.getField());
}
}
在這個示例中,抽象原型介面定義了克隆方法,具體原型類實現了該介面並提供了自己的克隆方法。客戶端通過克隆方法創建新對象,驗證新對象的屬性與原始對象相同。這個示例展示了原型模式的基本實現步驟。
6 典型應用場景
原型模式在以下情況下是典型的應用場景:
需要創建對象的成本較高:當對象的創建和初始化成本較高時,原型模式可以顯著提高性能。每次都使用構造函數創建對象可能會導致不必要的開銷,因此通過複製已有對象來創建新對象更為高效。
在電腦游戲中,創建和初始化複雜的游戲角色可能需要大量時間和資源。如果游戲需要大量相似的角色,可以使用原型模式來複制現有角色,節省創建時間。
對象的屬性變化頻繁:當對象的屬性需要經常變化,但你希望保持對象的初始狀態作為基礎,可以使用原型模式。這樣,你可以創建一個原型對象,並根據需要克隆它來創建新的對象。
在圖形設計工具中,用戶可以創建和編輯圖形對象,如圖形文本框。原始對象可以充當原型,用戶可以複製它來創建多個類似但具有不同文本內容的圖形文本框。
動態配置對象:當對象的屬性需要根據運行時配置或用戶輸入而變化時,原型模式很有用。你可以創建一個原型對象,然後根據需要修改其屬性,而無需重新構建對象。
在網站創建工具中,用戶可以創建網頁並自定義顏色、字體、佈局等屬性。原始網頁對象可以作為原型,用戶可以克隆它並根據自己的需求修改屬性。
保護性拷貝:原型模式可以用於創建對象的深拷貝,以保護原始對象免受外部修改的影響。這對於涉及敏感數據或狀態的對象非常有用。
在安全敏感的應用程式中,用戶身份驗證對象可能包含用戶的敏感信息。通過使用原型模式創建深拷貝,可以確保不會在外部修改原始對象的敏感數據。
總之,原型模式適用於需要創建對象的成本高、屬性變化頻繁、動態配置或需要保護性拷貝的場景。它提供了一種高效、靈活和可維護的方式來創建對象,併在許多領域中有廣泛的應用。
7 優缺點
優點:
提高性能:避免了對象的重覆初始化,提高了對象創建的效率。
簡化對象創建:客戶端代碼可以通過克隆來創建新對象,無需瞭解對象的具體構造方式。
動態配置對象:允許在運行時動態配置對象的屬性。
保護性拷貝:可以創建對象的深拷貝,保護原始對象免受修改的影響。
缺點:
需要實現克隆方法:每個具體原型類都需要實現克隆方法,這可能需要一些額外的工作。
淺克隆問題:預設的克隆操作是淺克隆,如果對象包含引用類型的成員變數,可能需要手動實現深克隆。
8 類似模式
在 Spring 框架中,使用了原型模式和單例模式來管理對象的創建和生命周期。
原型模式在 Spring 中的應用:
原型範圍(Scope)的 Bean:在 Spring 中,你可以將一個 Bean 配置為原型範圍,這意味著每次從 Spring 容器請求該 Bean 時,都會創建一個新的實例。這就是原型模式的應用,每次都克隆一個對象來創建新實例。這對於那些需要頻繁創建新對象的場景非常有用,因為每個請求都會得到一個全新的 Bean 實例,而不會共用狀態。
使用 prototype 作用域聲明 Bean:在 Spring 的配置文件或使用註解時,你可以明確將 Bean 的作用域聲明為 prototype,告訴 Spring 這個 Bean 是原型範圍的,從而使用原型模式來創建對象。
<bean id="myBean" class="com.example.MyBean" scope="prototype">
</bean>
單例模式在 Spring 中的應用:
單例範圍(Scope)的 Bean:預設情況下,Spring 中的 Bean 是單例範圍的,這意味著 Spring 容器只會創建一個 Bean 的實例,併在整個應用程式中共用這個實例。這就是單例模式的應用,確保一個類只有一個實例。
使用 singleton 作用域聲明 Bean:雖然預設是單例範圍,但你也可以顯式將 Bean 的作用域聲明為 singleton,以明確表達這一點。
<bean id="myBean" class="com.example.MyBean" scope="singleton">
</bean>
在 Spring 中,原型模式和單例模式的選擇取決於對象的生命周期和狀態需求。如果你需要一個共用狀態的單一實例,可以使用單例模式。如果需要每次請求都獲得一個全新的對象實例,可以使用原型模式。Spring 提供了這兩種範圍的支持,以滿足不同的業務需求。
9 小結
原型模式是一種用於創建對象的設計模式,它通過克隆現有對象來創建新對象,從而提高性能、簡化對象創建和支持動態配置對象的需求。原型模式在需要頻繁創建對象,或者需要保護對象不受修改影響的情況下非常有用。