java prototype 模式_JAVA设计模式之原型模式(prototype)

原型模式:

原型模式又叫克隆模式

Java自带克隆模式

实现克隆模式必须实现Cloneable

接口,如果不实现会发生java.lang.CloneNotSupportedException异常

当某个类的属性已经设定好需要创建很多相同属性值的对象的时候使用clone模式非常方便

使用clone模式不见得比传统的new方式性能高

浅克隆和深克隆

先看下面的代码,没有实现Cloneable接口

packagecom.srr.dp.clone;/*** (原型模式)克隆模式*/

public class Appler /*implements Cloneable*/{privateString clor;private intweight;private intvolume;privateStringBuilder descr;publicAppler(String clor) {this.clor =clor;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

@OverridepublicString toString() {return "Appler{" +

"clor='" + clor + '\'' +

", weight=" + weight +

", volume=" + volume +

", descr=" + descr +

'}';

}

}packagecom.srr.dp.clone;public classT {public static void main(String[] args) throwsCloneNotSupportedException {

Appler appler= new Appler("yellow");

Appler appler1=(Appler) appler.clone();

System.out.println(appler1);

}

}

运行结果:

33196a09c69c046d859b6bd957719b49.png

浅拷贝:

packagecom.srr.dp.clone;/*** (原型模式)克隆模式

* 浅拷贝*/

public class Appler implementsCloneable {privateString clor;private intweight;private intvolume;privateLocation loc;public Appler(String clor,int weight,intvolume,Location loc) {this.clor =clor;this.weight =weight;this.volume =volume;this.loc =loc;

}publicString getClor() {returnclor;

}public voidsetClor(String clor) {this.clor =clor;

}public intgetWeight() {returnweight;

}public void setWeight(intweight) {this.weight =weight;

}public intgetVolume() {returnvolume;

}public void setVolume(intvolume) {this.volume =volume;

}publicLocation getLoc() {returnloc;

}public voidsetLoc(Location loc) {this.loc =loc;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {//loc = (Locaton) loc.clone();

return super.clone();

}

@OverridepublicString toString() {return "Appler{" +

"clor='" + clor + '\'' +

", weight=" + weight +

", volume=" + volume +

", loc=" + loc +

'}';

}

}packagecom.srr.dp.clone;public classLocation {

String name;publicLocation(String name){this.name =name;

}

@OverridepublicString toString() {return "Locaton{" +

"name='" + name + '\'' +

'}';

}

}packagecom.srr.dp.clone;/*** 测试代码*/

public classT {public static void main(String[] args) throwsCloneNotSupportedException {

Appler appler= new Appler("yellow",1,1,new Location("洛川"));

Appler appler1=(Appler) appler.clone();

appler.setClor("red");

appler.getLoc().name= "宝鸡";

System.out.println("appler1 = "+appler1);

System.out.println("appler = "+appler);

}

}

运行结果:

2c486b88895717451161a0aaa6806ace.png

从结果发现,当改变appler 的颜色还有location的值后,拷贝的apper1对象的颜色未发生改变但是location发生了改变。

这就是浅拷贝,引用对象无法保证拷贝之后完全独立只是拷贝了地址但是地址指向的对象是共享的,

虽然String类型也是引用类型但是共享常量池所以不会有这个问题。

那么如何让引用类型拷贝之后独立呢?

那么就要使用深拷贝请看如下代码:

packagecom.srr.dp.clone;/*** (原型模式)克隆模式

* 浅拷贝*/

public class Appler implementsCloneable {privateString clor;private intweight;private intvolume;privateLocation loc;public Appler(String clor,int weight,intvolume,Location loc) {this.clor =clor;this.weight =weight;this.volume =volume;this.loc =loc;

}publicString getClor() {returnclor;

}public voidsetClor(String clor) {this.clor =clor;

}public intgetWeight() {returnweight;

}public void setWeight(intweight) {this.weight =weight;

}public intgetVolume() {returnvolume;

}public void setVolume(intvolume) {this.volume =volume;

}publicLocation getLoc() {returnloc;

}public voidsetLoc(Location loc) {this.loc =loc;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {

Appler appler= (Appler)super.clone();

appler.loc=(Location) loc.clone();;returnappler;

}

@OverridepublicString toString() {return "Appler{" +

"clor='" + clor + '\'' +

", weight=" + weight +

", volume=" + volume +

", loc=" + loc +

'}';

}

}packagecom.srr.dp.clone;public class Location implementsCloneable{

String name;publicLocation(String name){this.name =name;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

@OverridepublicString toString() {return "Locaton{" +

"name='" + name + '\'' +

'}';

}

}packagecom.srr.dp.clone;/*** 测试代码*/

public classT {public static void main(String[] args) throwsCloneNotSupportedException {

Appler appler= new Appler("yellow",1,1,new Location("洛川"));

Appler appler1=(Appler) appler.clone();

appler.setClor("red");

appler.getLoc().name= "宝鸡";

System.out.println("appler1 = "+appler1);

System.out.println("appler = "+appler);

}

}

运行结果:

16b0b42ead314af099b79cd3eab981ce.png

从结果发现,当改变appler 的颜色还有location的值后,拷贝的apper1对象的颜色未发生改变location也发生了改变。

上面说到String类型的拷贝不存在浅拷贝的问题,那么StringBuilder或者StringBuffer呢,鉴于篇幅这里使用StringBuilder来举例

请看代码:

packagecom.srr.dp.clone;/*** (原型模式)克隆模式

* 浅拷贝*/

public class Appler implementsCloneable {privateString color;private intweight;private intvolume;privateLocation loc;publicString getColor() {returncolor;

}publicStringBuilder getDesc() {returndesc;

}public voidsetDesc(StringBuilder desc) {this.desc =desc;

}private StringBuilder desc = new StringBuilder("好吃");public Appler(String color,int weight,intvolume,Location loc) {this.color =color;this.weight =weight;this.volume =volume;this.loc =loc;

}publicString getClor() {returncolor;

}public voidsetColor(String color) {this.color =color;

}public intgetWeight() {returnweight;

}public void setWeight(intweight) {this.weight =weight;

}public intgetVolume() {returnvolume;

}public void setVolume(intvolume) {this.volume =volume;

}publicLocation getLoc() {returnloc;

}public voidsetLoc(Location loc) {this.loc =loc;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {

Appler appler= (Appler)super.clone();

appler.loc=(Location) loc.clone();returnappler;

}

@OverridepublicString toString() {return "Appler{" +

"color='" + color + '\'' +

", weight=" + weight +

", volume=" + volume +

", loc=" + loc +

", desc=" + desc +

'}';

}

}packagecom.srr.dp.clone;public class Location implementsCloneable{

String name;publicLocation(String name){this.name =name;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

@OverridepublicString toString() {return "Locaton{" +

"name='" + name + '\'' +

'}';

}

}packagecom.srr.dp.clone;/*** 测试代码*/

public classT {public static void main(String[] args) throwsCloneNotSupportedException {

Appler appler= new Appler("yellow",1,1,new Location("洛川"));

Appler appler1=(Appler) appler.clone();

appler.getDesc().append("得不得了");

appler.getLoc().name= "宝鸡";

System.out.println("appler1 = "+appler1);

System.out.println("appler = "+appler);

}

}

运行结果:

edc79b814a80bfaf1e68be49596c5605.png

这是是后你会发现当appler的desc值发生改变之后,apper1的值也发生改变了,说明StringBuilder的拷贝方式为浅拷贝,那么如何实现深拷贝呢

请看代码:

packagecom.srr.dp.clone;/*** (原型模式)克隆模式

* 浅拷贝*/

public class Appler implementsCloneable {privateString color;private intweight;private intvolume;privateLocation loc;publicString getColor() {returncolor;

}publicStringBuilder getDesc() {returndesc;

}public voidsetDesc(StringBuilder desc) {this.desc =desc;

}private StringBuilder desc = new StringBuilder("好吃");public Appler(String color,int weight,intvolume,Location loc) {this.color =color;this.weight =weight;this.volume =volume;this.loc =loc;

}publicString getClor() {returncolor;

}public voidsetColor(String color) {this.color =color;

}public intgetWeight() {returnweight;

}public void setWeight(intweight) {this.weight =weight;

}public intgetVolume() {returnvolume;

}public void setVolume(intvolume) {this.volume =volume;

}publicLocation getLoc() {returnloc;

}public voidsetLoc(Location loc) {this.loc =loc;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {

Appler appler= (Appler)super.clone();

appler.loc=(Location) loc.clone();

appler.desc= new StringBuilder(this.desc);returnappler;

}

@OverridepublicString toString() {return "Appler{" +

"color='" + color + '\'' +

", weight=" + weight +

", volume=" + volume +

", loc=" + loc +

", desc=" + desc +

'}';

}

}packagecom.srr.dp.clone;public class Location implementsCloneable{

String name;publicLocation(String name){this.name =name;

}

@Overrideprotected Object clone() throwsCloneNotSupportedException {return super.clone();

}

@OverridepublicString toString() {return "Locaton{" +

"name='" + name + '\'' +

'}';

}

}packagecom.srr.dp.clone;/*** 测试代码*/

public classT {public static void main(String[] args) throwsCloneNotSupportedException {

Appler appler= new Appler("yellow",1,1,new Location("洛川"));

Appler appler1=(Appler) appler.clone();

appler.getDesc().append("得不得了");

appler.getLoc().name= "宝鸡";

System.out.println("appler1 = "+appler1);

System.out.println("appler = "+appler);

}

}

运行结果:

f4034a4b20c7279e76264bc8c00f5775.png

这是是后你会发现当appler的desc值发生改变之后,apper1的值并没有发生改变。

写到这里原型模式就介绍完了。

原创不易,请多多支持!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值