您的位置:首页 > 编程语言 > Java开发

Java设计模式——原型模式

2016-12-22 15:48 267 查看
    原型模式既简单、又好用,需要实现Cloneable接口,说的纯粹点,原型模式的作用就是克隆。下面举一个例子,我们来克隆绵羊:

绵羊类,实现Cloneable接口:

public class Sheep implements Cloneable {

private String name = "小白";
private String color = "白色";

@Override
public Sheep clone() throws CloneNotSupportedException {
Sheep sheep = (Sheep) super.clone();
sheep.name = this.name;
sheep.color = this.color;
return sheep;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
'}';
}
}


接下来就可以测试了:

try {
//新建一个绵羊
Sheep sheep = new Sheep();
//克隆一个绵羊
Sheep cloneSheep = sheep.clone();
//修改克隆羊的属性
cloneSheep.setName("小红");
cloneSheep.setColor("红色");

Log.d("test", sheep.toString());
Log.d("test", cloneSheep.toString());
Log.d("test", sheep.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}


打印出的log:

test: Sheep{name='小白', color='白色'}
test: Sheep{name='小红', color='红色'}
test: Sheep{name='小白', color='白色'}


我们发现,修改了克隆体的属性,并没有修改原样本的属性,这就是原型模式的作用;

接下来我们进一步做实验,给每个绵羊添加几个爱好(hobby):

public class Sheep implements Cloneable {

private String name = "小白";
private String color = "白色";
private ArrayList<String> hobby = new ArrayList<>();

@Override
public Sheep clone() throws CloneNotSupportedException {

4000
Sheep sheep = (Sheep) super.clone();
sheep.name = this.name;
sheep.color = this.color;
sheep.hobby = this.hobby;
return sheep;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

public ArrayList<String> getHobby() {
return hobby;
}

public void setHobby(ArrayList<String> hobby) {
this.hobby = hobby;
}

@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", color='" + color + '\'' +
", hobby=" + hobby +
'}';
}
}


接下来我们测试:

try {
//新建一个绵羊
Sheep sheep = new Sheep();
ArrayList<String> hobby = sheep.getHobby();
hobby.add("草");
hobby.add("空气");
Log.d("test", "sheep = " + sheep.toString());

//克隆一个绵羊
Sheep cloneSheep = sheep.clone();
//修改克隆羊的属性
cloneSheep.setName("小红");
cloneSheep.setColor("红色");
ArrayList<String> hobby2 = cloneSheep.getHobby();
hobby2.add("胡萝卜");
hobby2.add("大海");

Log.d("test", "cloneSheep = " + cloneSheep.toString());
Log.d("test", "sheep = " + sheep.toString());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}


我们看输出的log:

sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]}
cloneSheep = Sheep{name='小红', color='红色', hobby=[草, 空气, 胡萝卜, 大海]}
sheep = Sheep{name='小白', color='白色', hobby=[草, 空气, 胡萝卜, 大海]}


我们发现,修改克隆体后样本也改变了,这就涉及到了深拷贝与浅拷贝的知识:浅拷贝也叫影子拷贝,他其实并不是真的拷贝了一份,而是拷贝后的字段引用了样本字段的地址,指向了样本字段,与样本字段共用一个。下面我们修改一下程序的clone方法:

@Override
public Sheep clone() throws CloneNotSupportedException {
Sheep sheep = (Sheep) super.clone();
sheep.name = this.name;
sheep.color = this.color;
sheep.hobby = (ArrayList<String>) this.hobby.clone();
return sheep;
}


接下来测试,测试代码不做修改,看log:

sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]}
cloneSheep = Sheep{name='小红', color='红色', hobby=[草, 空气, 胡萝卜, 大海]}
sheep = Sheep{name='小白', color='白色', hobby=[草, 空气]}


没错,这就是我们想要的效果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: