原型模式就是通過一個原型對象來表明要創建的對象類型,然后用復制這個原型對象的方法來創建更多同類型的對象。
自己對原型模式簡單理解的原理圖如下:
具體屬性沒有添加:

原型模式里面關鍵點就在一個Cloneable接口和clone方法的重寫
下面就通過一個配鑰匙的例子簡單的寫了一個程序,起初一個一個抽象類,這樣可以重寫clone方法,如果是接口的話就得到子類里面把重寫的方法具體聲明,這樣的話對于程序的復用性不是很好,于是就寫了一個抽象的類KeyPrototype然后,寫了兩個子類繼承一個客戶端,代碼如下:
~~~
package com.designpattern.prototype;
public abstract class KeyPrototype implements Cloneable {
private String color;
private float length;
private float thick;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return this.getClass() + " -> Color:" + this.getColor() + " Length:"
+ this.getLength() + " Thick:" + this.getThick();
}
public String getColor() {
return color;
}
public float getLength() {
return length;
}
public float getThick() {
return thick;
}
public void setColor(String color) {
this.color = color;
}
public void setLength(float length) {
this.length = length;
}
public void setThick(float thick) {
this.thick = thick;
}
}
~~~
~~~
package com.designpattern.prototype;
public class CopperKey extends KeyPrototype {
}
~~~
~~~
package com.designpattern.prototype;
public class AluminiumKey extends KeyPrototype {
}
~~~
~~~
package com.designpattern.prototype;
public class Client {
public static void main(String[] args) {
KeyPrototype copperkey = new CopperKey();
copperkey.setColor("red");
copperkey.setLength(12);
copperkey.setThick(2);
System.out.println(copperkey);
try {
KeyPrototype aluminaumkey = (KeyPrototype) copperkey.clone();
aluminaumkey.setColor("yellow");
aluminaumkey.setLength(10);
aluminaumkey.setThick(5);
System.out.println(aluminaumkey);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
~~~
~~~
class com.designpattern.prototype.CopperKey -> Color:red Length:12.0 Thick:2.0
class com.designpattern.prototype.CopperKey -> Color:yellow Length:10.0 Thick:5.0
~~~
這樣就簡單對前者進行的復制,很顯然他們并不是一個對象,里面關于clone的東西做了一個簡單的總結
同時來證明他們確實是兩個對象,就是改動里面的屬性不互相影響:
首先我創建了一個Dog類
~~~
package com.note.clone;
public class Dog/* implements Cloneable */{
private String color;
private String name;
public Dog(String name,String color){
this.name = name;
this.color = color;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/* @Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}*/
@Override
public String toString() {
return this.getClass()+" "+this.getName()+" "+this.getColor();
}
}
~~~
然后寫了一個Tom類,其中Tom類里面有私有屬性Dog
~~~
package com.note.clone;
public class Tom implements Cloneable {
private String color;
private Dog dog = new Dog("mimi", "yellow");;
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
Tom o = null;
o = (Tom)super.clone();
// o.setDog((Dog)o.getDog().clone());
return o;
}
public String getColor() {
return color;
}
public Dog getDog() {
return dog;
}
public String getName() {
return name;
}
public void setColor(String color) {
this.color = color;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return this.getClass() + " " + this.getName() + " " + this.getColor()
+ "\n" + "Dog:" + this.dog;
}
}
~~~
然后寫了一個People類簡單的對上述的兩個程序進行測試:
~~~
package com.note.clone;
public class People {
public static void main(String[] args) {
Tom tom = new Tom();
tom.setName("Tom");
tom.setColor("blue");
System.out.println(tom);
System.out.println();
try {
Tom tylo = (Tom) tom.clone();
tylo.setName("tylo");
tylo.setColor("red");
tylo.getDog().setName("lucky");
tylo.getDog().setColor("green");
System.out.println(tylo);
System.out.println();
System.out.println(tom);
System.out.println();
Dog dog = tylo.getDog();
dog.setName("hello");
dog.setColor("white");
System.out.println(tylo);
System.out.println();
System.out.println(tom);
System.out.println();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
~~~
運行結果如下:
~~~
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow
class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog lucky green
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog lucky green
class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog hello white
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog hello white
~~~
這樣很明確的表明了對于這兩個對象的屬性,自己的屬性除了Dog以外都是自己的,沒有對著對方的屬性的改變而改變,但是Dog屬性,兩個對象的屬性是一樣的
那么這里就到了深度克隆
我們把Dog和Tom里注釋掉的內容打開再運行People程序,運行結果如下:
~~~
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow
class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog lucky green
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow
class com.note.clone.Tom tylo red
Dog:class com.note.clone.Dog hello white
class com.note.clone.Tom Tom blue
Dog:class com.note.clone.Dog mimi yellow
~~~
很明顯發現,兩個對象的Dog屬性也沒有互相影響,說明了他們不是用的一個引用,這樣也證明了上面的例子,他們分別是一個對象,達到了克隆復用的應用。
在原型模式中,可以動態的添加產品分類,而且對整體結構沒有影響。
由于原型模式需要給每一個類都配備一個克隆方法,這就需要在這幾類的時候通盤考慮,因為在已有類的基礎上來添加clone操作時比較困難的,而且原型模式在實現深層的復制時,需要編寫一定量的代碼。
- 前言
- 前言(目錄、源碼、資料)
- (一)簡單工廠模式(SimpleFatory)
- (二)工廠方法模式(FactoryMethod)
- (三)抽象工廠模式(AbstractFactory)
- (四)創建者模式(Builder)
- (五)原型模式(Prototype)
- (六)單例模式(Singleton)
- (七)外觀模式(Facade)
- (八)適配器模式(Adapter)
- (九)代理模式(Proxy)
- (十)裝飾模式(Decorator)
- (十一)橋模式(birdge)
- (十二)組合模式(Composite)
- (十三)享元模式(Flyweight)
- (十四)模板方法模式(Template)
- (十五)觀察者模式(Observer)
- (十六)狀態模式(State)