原型模式
學(xué)習(xí)目標
是什么孝治?
淺復(fù)制
深復(fù)制
原型模式其實就是從一個對象再創(chuàng)建另外一個可定制的對象狂芋,而且不需知道任何創(chuàng)建細節(jié)
在現(xiàn)實中有這樣的場景。
public class Money {
//面額
private int num;
//印刷時間
private String time;
public Money(){
System.out.println("賺錢(創(chuàng)建)中黎休。欢揖。陶耍。");
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
}
大家都知道賺錢是很辛苦的,當我們想賺很多錢的時候她混,通過都是這樣
Money m1 = new Money();
m1.setNum(1);
m1.setTime("2014");
Money m2 = new Money();
m1.setNum(5);
m1.setTime("2014");
Money m2 = new Money();
m1.setNum(10);
m1.setTime("2014");
OMG!簡直要瘋烈钞。。坤按。毯欣。
只是部分屬性不同,卻需要多次創(chuàng)建對象臭脓,這樣代碼看起來十分臃腫且沒有效率
那么如何來避免多次實例化對象呢酗钞?
下面看看原型模式的簡單實現(xiàn)
實現(xiàn)Cloneable接口
public class Money implements Cloneable {
//面額
private int num;
//印刷時間
private String time;
public Money(){
System.out.println("賺錢(創(chuàng)建)中。。砚作。");
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
@Override
public String toString() {
return "Money [num=" + num + ", time=" + time + "]";
}
@Override
public Money clone(){
try {
return (Money) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}```
測試一下~
```java
Money m1 = new Money();
m1.setNum(1);
m1.setTime("2014");
Money m2 = m1.clone();
m2.setNum(10000);
System.out.println(m1);
System.out.println(m2);
運行結(jié)果~
賺錢(創(chuàng)建)中窘奏。。葫录。
Money [num=1, time=2014]
Money [num=10000, time=2014]
哇哈哈哈哈哈着裹,發(fā)現(xiàn)錢都不用賺了,可以復(fù)制了
值得注意的是米同,如果類中引用類型的對象骇扇,那么就只復(fù)制了引用但不復(fù)制引用的對象
,則只是復(fù)制了引用面粮,但沒有負責引用的對象少孝,因此,復(fù)制的對象的原本的對象都是同一個引用
假設(shè)我們給Money添加一個生產(chǎn)money的工廠類
//生產(chǎn)Money的工廠
public class Factory {
private String name;
熬苍。稍走。。省略
TEST
Money m1 = new Money();
m1.setNum(1);
m1.setTime("2014");
m1.setFactory(new Factory("龍崗印刷廠"));
Money m2 = m1.clone();
m2.setNum(10000);
m2.getFactory().setName("小梅沙印刷廠");
System.out.println(m1.getFactory().getName());
System.out.println(m2.getFactory().getName());
運行·結(jié)果·
賺錢(創(chuàng)建)中冷溃。。梦裂。
小梅沙印刷廠
小梅沙印刷廠
0.0發(fā)現(xiàn)工廠名稱隨著修改了似枕,其實Factory都是指向同一個對象
沒有復(fù)制引用類型,這個就叫做“淺復(fù)制“
淺復(fù)制:被復(fù)制的對象的所有變量都含有原來對象的值年柠,而所有的對其他對象的引用都仍然指向原來的對象凿歼。
那么如何解決呢?
我們想把的引用對象的變量指向復(fù)制過來的對象冗恨,不是指向原來被引用的對象
有點繞口答憔。。掀抹。這個就是”深復(fù)制"了
其實相當簡單虐拓,看下代碼就知道了
讓Factory也實現(xiàn)Cloneable
@Override
protected Factory clone() {
// TODO Auto-generated method stub
try {
return (Factory) super.clone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
在Money中,完成對Factory的copy
public Money(Factory factory) {
this.factory = factory.clone();
}```
然后就是money的clone
```java
@Override
public Money clone() {
Money money = null;
money = new Money(this.factory);
money.setNum(this.num);
money.setTime(this.time);
return money;
}```
讀《大話設(shè)計模式》筆記之~