原型模式本身就是一种很简单的模式,在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方法,实现浅拷贝@Overridepublic 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();}}
}