一、什么是原型模式
Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。
使用Prototype模式创建的实例,具有与原型一样的数据。
二、原型模式的特点
1. 由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
2.目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型
对象具有相同的结构,还与原型对象具有相同的值。
3.根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
三、原型模式应用场景
1)在创建对象的时候,我们不只是希望被创建的对象继承
其基类的基本结构,还希望继承原型对象的数据。
2) 希望对目标对象的修改不影响既有的原型对象(深度克
隆的时候可以完全互不影响)。
3)隐藏克隆操作的细节。很多时候,对对象本身的克隆需
要涉及到类本身的数据细节。
四、代码示例
1.创建Person类,实现Cloneable接口
public class Person implements Cloneable{ private String name;//姓名 private int age;//年龄 private String sex;//性别 public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public void setSex(String sex) { this.sex = sex; } public String getName() { return name; } public int getAge() { return age; } public String getSex() { return sex; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } public Person clone(){ try { return (Person) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } } }
实例化一个对象person1和person2,person2和person1只有姓名不同,这时,可以用person1位原型,创建person2
实现接口Cloneable
创建clone方法:super.clone()
public static void main(String[] args) { Person per1 = new Person(); per1.setName("王八"); per1.setAge(24); per1.setSex("男"); Person per2 = per1.clone(); /* per2.setName("王八2"); per2.setAge(24); per2.setSex("男");*/ per2.setName("赵流"); System.out.println(per1.toString()); System.out.println(per2.toString()); System.out.println(per1 == per2); }
输出结果:
Person{name='王八', age=24, sex='男'}
Person{name='赵流', age=24, sex='男'}
false //表明两个对象指向不同的引用
2.深度克隆:给Person添加一个朋友friends属性,
在进行克隆,发现这时候per1和per2是一样的值
Person per1 = new Person();
List<String> friends = new ArrayList<String>(); friends.add("利拉德"); friends.add("麦科勒姆"); per1.setFriends(friends); Person per2 = per1.clone(); friends.add("坎特"); per1.setFriends(friends); System.out.println(per1.getFriends()); System.out.println(per2.getFriends());
[利拉德, 麦科勒姆, 坎特]
[利拉德, 麦科勒姆, 坎特]
而我们期望的结果应是
[利拉德, 麦科勒姆, 坎特]
[利拉德, 麦科勒姆]
所以这时候需要对克隆方法进行改进,进行深度克隆,修改克隆方法如下:
public Person clone(){ try { Person person = (Person) super.clone();//先克隆一个原型对象 List<String> newFriends = new ArrayList<String>(); for(String friend:this.getFriends()){//当前对象获取朋友 newFriends.add(friend);//添加到新的朋友中 } person.setFriends(newFriends); return person; } catch (CloneNotSupportedException e) { e.printStackTrace(); return null; } }