原型模式是一種創(chuàng)建型設(shè)計(jì)模式,使調(diào)用方能夠復(fù)制已有對(duì)象,而又無(wú)需使代碼依賴它們所屬的類。當(dāng)有一個(gè)類的實(shí)例(原型),并且想通過(guò)復(fù)制原型來(lái)創(chuàng)建新對(duì)象時(shí),通常會(huì)使用原型模式。
The Prototype pattern is generally used when we have an instance of the class (prototype) and we'd like to
create new objects by just copying the prototype.
結(jié)構(gòu)設(shè)計(jì)
原型模式包含如下角色:
Prototype,原型類,用來(lái)聲明克隆方法。在絕大多數(shù)情況下,只會(huì)有一個(gè)名為 clone 的方法。
ConcretePrototype,具體原型類,用來(lái)實(shí)現(xiàn)克隆方法。除了將原始對(duì)象的數(shù)據(jù)復(fù)制到克隆體中之外,該方法有時(shí)還需處理克隆過(guò)程中的極端情況, 例如克隆關(guān)聯(lián)對(duì)象和梳理遞歸依賴等等。
原型模式類圖表示如下:
偽代碼實(shí)現(xiàn)
接下來(lái)將使用代碼介紹下原型模式的實(shí)現(xiàn)。
// 1.定義原型接口,用來(lái)聲明克隆方法
public interface Prototype {
/**
* 復(fù)制對(duì)象
*
* @return 復(fù)制后的對(duì)象
*/
Prototype clone();
}
// 2、定義具體原型類(ConcretePrototype),用來(lái)實(shí)現(xiàn)克隆方法
public class ConcretePrototype implements Prototype {
private String field;
public ConcretePrototype() {
}
public String getField() {
return field;
}
public ConcretePrototype(String field) {
this.field = field;
}
@Override
public Prototype clone() {
ConcretePrototype concretePrototype = new ConcretePrototype();
concretePrototype.field = this.field;
return concretePrototype;
}
}
// 3、客戶端調(diào)用
public class PrototypeClient {
public PrototypeClient() {
}
// 調(diào)用方式:調(diào)用具體原型實(shí)例的克隆方法
public void test() {
Prototype concretePrototype = new ConcretePrototype("foo");
ConcretePrototype clonedPrototype = (ConcretePrototype) concretePrototype.clone();
System.out.println(clonedPrototype.getField());
}
}
需要說(shuō)明的是,對(duì)于Java語(yǔ)言來(lái)說(shuō),Object基類已經(jīng)提供了一個(gè)clone的保護(hù)方法,用于實(shí)現(xiàn)對(duì)象的淺復(fù)制。注意,只有實(shí)現(xiàn)了Cloneable接口才可以調(diào)用該方法,
否則拋出CloneNotSupportedException異常。更多clone方法的介紹,可以參考筆者之前的文章。
適用場(chǎng)景
在以下情況下可以考慮使用原型模式:
(1) 如果需要復(fù)制一些對(duì)象,同時(shí)又希望代碼獨(dú)立于這些對(duì)象所屬的具體類,可以使用原型模式。
例如,代碼里需要處理第三方接口傳遞過(guò)來(lái)的對(duì)象時(shí),即使不考慮代碼耦合的情況, 調(diào)用方的代碼也不能依賴這些對(duì)象所屬的具體類,因?yàn)闊o(wú)法知道它們的具體信息。
原型模式,可以為調(diào)用方提供一個(gè)通用接口,調(diào)用方可通過(guò)這一接口與所有實(shí)現(xiàn)了克隆的對(duì)象進(jìn)行交互,它也使得調(diào)用方與其所克隆的對(duì)象具體類獨(dú)立開(kāi)來(lái)。
(2) 如果子類的區(qū)別僅在于其對(duì)象的初始化方式,那么可以使用原型模式來(lái)減少子類的數(shù)量。
在原型模式中, 可以使用一系列預(yù)生成的、各種類型的對(duì)象作為原型(原型對(duì)象池)。客戶端不必根據(jù)需求對(duì)子類進(jìn)行實(shí)例化,只需找到合適的原型并對(duì)其進(jìn)行克隆即可。
優(yōu)缺點(diǎn)
原型模式有以下優(yōu)點(diǎn):
(1) 將對(duì)象克隆與對(duì)象所屬的具體類分離(解耦),避免克隆對(duì)象與具體類的緊耦合。
(2) 簡(jiǎn)化了復(fù)雜對(duì)象的初始化代碼。對(duì)一些復(fù)雜對(duì)象,可以通過(guò)提供克隆方法來(lái)簡(jiǎn)化調(diào)用方的使用。
(3) 提供了除繼承以外的方式來(lái)實(shí)現(xiàn)復(fù)雜對(duì)象的初始化。繼承建立了子類與父類的強(qiáng)耦合,如果可以,盡量不要使用繼承。
但是原型模式也存在以下缺點(diǎn):
(1) 在重寫(xiě)克隆方法時(shí),對(duì)于復(fù)雜對(duì)象的關(guān)聯(lián)對(duì)象或遞歸依賴等處理相比麻煩一些。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-621887.html
參考
《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides 著 李英軍, 馬曉星 等譯
https://www.cnblogs.com/adamjwh/p/9033550.html 簡(jiǎn)說(shuō)設(shè)計(jì)模式——原型模式
https://refactoringguru.cn/design-patterns/prototype 原型模式
https://www.baeldung.com/java-pattern-prototype Prototype Pattern in Java文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-621887.html
到了這里,關(guān)于原型模式(Prototype)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!