释义
原型模式是一种创建型设计模式,该模式允许一个对象再创建另外一个可定制的对象,根本无需知道任何如何创建的细节,工作原理是通过将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。
原型模式需要先有一个原型,在Java开发中,原型就可以是一个普通的类对象。
案例
public class Person implements Cloneable {
private String name;
private Integer age;
private Car car;
public Person(String name, Integer age, Car car) {
this.name = name;
this.age = age;
this.car = car;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
public Car getCar() {
return car;
}
@Override
protected Person clone() {
Person person;
try {
person = (Person)super.clone();
person.car = car.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
return person;
}
}
public class Car implements Cloneable{
private String brand;
private String type;
public Car(String brand, String type) {
this.brand = brand;
this.type = type;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
protected Car clone(){
Car car;
try {
car = (Car)super.clone();
} catch (CloneNotSupportedException e) {
throw new RuntimeException(e);
}
return car;
}
}
这里创建了一个普通的Person类和Car类,当我们使用这两个类的时候,就可以用new的方式来进行创建,并进行复制。这里这两个类就可以称之为一种原型。通过示例代码看出,这两个类分别实现了Cloneable接口,并且重写了clone方法。这里实现Cloneable接口是一个标记接口,源码中该接口没有任何方法,类似于Spring中的注解标记。只是为了表明该类可以被克隆,也就是重写的clone方法可以完整的执行下来。
public static void main(String[] args) {
Car car = new Car("奔驰", "S500");
Person prototype = new Person("我",18,car);
System.out.println(prototype.getName());
Person clone = prototype.clone();
System.out.println(clone.getName());
car.setType("S600");
System.out.println(clone.getCar().getBrand());
}
这里列出调用方式,创建了一个Car对象并创建了一个Person对象,将Car复制给Person,然后到这里,Person可以当作原型来进行克隆操作。复制出一个一模一样的Person来。
深拷贝和浅拷贝
这里是原型复制中会产生的一个问题,当上面的代码的Car对象中不实现Cloneable的时候,我们直接clone整个Person对象的话,由于复制的是引用地址,导致Car被两个不同的Person对象使用,尽管两个Person是一样的信息。这样对其中一个Person修改的时候,另一个Person的Car对象也会被修改。所以需要对Car也进行一次复制。这种对引用类型只复制引用地址的行为就叫做浅拷贝,而整体全部复制过来的情况就是一种深拷贝。