原型模式本身就是一种很简单的模式,在Java当中,由于内置了Cloneable 接口,就使得原型模式在Java中的实现变得非常简单。UML图如下:
我们来举一个生成新员工的例子来帮助大家理解。
import java.util.Date;
public class Employee implements Cloneable {
private String id;
private String name;
private Date hireDate;
private transient Address address; // 注意:transient关键字表示此字段不参与序列化,这里假设地址不需要深拷贝
public Employee(String id, String name, Date hireDate, Address address) {
this.id = id;
this.name = name;
this.hireDate = (Date) hireDate.clone(); // 防止原始hireDate被修改
this.address = address;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public Date getHireDate() {
return (Date) hireDate.clone(); // 返回原始hireDate的副本
}
public Address getAddress() {
return address;
}
// 重写Object的clone方法,实现浅拷贝
@Override
public Employee clone() throws CloneNotSupportedException {
Employee clonedEmployee = (Employee) super.clone();
// 如果有引用类型字段需要深拷贝,需要在这里进行额外处理
// 例如,如果Address也需要深拷贝,可以添加如下代码:
// clonedEmployee.address = address.clone();
return clonedEmployee;
}
}
class Address implements Cloneable {
private String street;
private String city;
private String country;
public Address(String street, String city, String country) {
this.street = street;
this.city = city;
this.country = country;
}
// 提供Address的克隆方法实现深拷贝
public Address clone() {
return new Address(street, city, country);
}
// ... getters and setters ...
}
public class PrototypeDemo {
public static void main(String[] args) {
try {
// 创建原始员工对象
Address address = new Address("123 Main St", "Anytown", "USA");
Employee original = new Employee("001", "John Doe", new Date(), address);
// 使用clone方法创建新员工对象
Employee cloned = original.clone();
// 修改克隆对象的属性,验证克隆是否成功
cloned.setName("Jane Doe");
cloned.getAddress().setCity("Another City");
System.out.println("Original Employee:");
System.out.println("ID: " + original.getId());
System.out.println("Name: " + original.getName());
System.out.println("Hire Date: " + original.getHireDate());
System.out.println("Address: " + original.getAddress());
System.out.println("\nCloned Employee:");
System.out.println("ID: " + cloned.getId());
System.out.println("Name: " + cloned.getName());
System.out.println("Hire Date: " + cloned.getHireDate());
System.out.println("Address: " + cloned.getAddress());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}