什么是原型模式
原型模式是一种创建型设计模式,它允许您使用现有对象来创建新对象,而不必从头开始编写代码。在Java中,原型模式可以实现Cloneable接口来复制对象。原型模式将克隆对象的责任委托给原型对象,从而避免了像工厂方法一样在每次创建对象时重新初始化它们。
为什么使用原型模式
原型模式可以帮助我们避免从头开始编写代码,从而节省时间和资源。通过使用现有对象来创建新对象,原型模式可以提供更好的性能和更少的内存消耗。此外,原型模式可以为我们提供一种更灵活的方式来创建对象,因为它可以根据需要动态地创建实例。
工作中用在哪里
在Android开发中,原型模式常常被用于创建新的Activity或Fragment实例。比如,我们可以创建一个基础的Activity或Fragment,并在其中定义一些必要的属性和方法。然后,我们可以使用这个基础实例作为原型,通过复制原型实例的属性和方法来创建新的实例,从而节省了创建新实例的工作量。
举个例子,假设我们需要在应用中创建多个具有相似功能和UI样式的Fragment实例,我们可以创建一个基础的Fragment实例,并将其定义为原型。然后,我们可以使用原型模式来复制这个基础实例,并根据需要修改一些属性和方法,从而创建新的Fragment实例。
特点
1、由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。
2、目标对象是原型对象的一个克隆。也就是说,通过原型模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。
3、根据对象克隆深度层次的不同,有浅度克隆与深度克隆。
优缺点
1、优点
(1)减少内存消耗,系统资源占用少,所有实例共享同一个方法,不会创建多个。
(2)原型对象继承时,子类在重写父类原型方法时很方便,可以调用父类方法,再扩展。
2、缺点
优点(1)既是最大的优点,也同样带来了一个严重的问题,如果共享的对象是引用对象(如array)则也会造成多个实例共享同一个array,很可能会相互影响。
设计思路
原型模式的设计思路是创建一个原型对象,然后通过克隆它来创建其他对象。原型对象实现Cloneable接口,这样我们就可以使用其clone()方法来创建新对象。在Java中,原型模式通常使用Object类的clone()方法实现。
浅拷贝和深拷贝
浅拷贝只复制指向某个对象的指针,而不是复制对象本身,新旧对象还是共享同一块内存。
深拷贝会另外创建一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
原型模式的代码实现
我们将使用一个简单的示例来演示原型模式的实现。我们将创建一个User类,它包含id和name属性。我们将创建一个原型对象,然后使用它来创建其他用户对象。这是一个完整的Java类的代码示例:
public class User implements Cloneable {
private int id;
private String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
在上面的代码中,我们实现了Cloneable接口并重写了clone()方法来实现原型模式。现在,我们将使用这个原型对象来创建其他对象:
public class PrototypeApp {
public static void main(String[] args) throws CloneNotSupportedException {
User prototype = new User(1, "John");
User user1 = (User) prototype.clone();
user1.setId(2);
User user2 = (User) prototype.clone();
user2.setId(3);
System.out.println("Prototype User: " + prototype.getId() + " - " + prototype.getName());
System.out.println("User 1: " + user1.getId() + " - " + user1.getName());
System.out.println("User 2: " + user2.getId() + " - " + user2.getName());
}
}
在上面的代码中,我们创建了一个原型对象,并使用它来创建User对象。我们使用clone()方法来复制原型对象,并设置新的id属性。然后,我们打印每个用户对象的id和name属性。输出如下:
Prototype User: 1 - John
User 1: 2 - John
User 2: 3 - John
JDK中的原型模式
原型模式的本质是拷贝原型来创建新的对象,拷贝是比new更快的创建对象方法,当需要大批量创建新对象而且都是同一个类的对象的时候可以考虑原型模式。但要注意一般的克隆只是浅克隆(浅克隆:只是对象的hash值不一样,但是对象里面的对象成员变量的hash值是一样的)有些场景可能需要深克隆,这时我们就需要重写clone方法,以ArrayList为例:
总结
原型模式是一种非常有用的创建型设计模式,它可以帮助我们避免从头开始编写代码,从而节省时间和资源。通过使用现有对象来创建新对象,原型模式可以提供更好的性能和更少的内存消耗。此外,原型模式可以为我们提供一种更灵活的方式来创建对象,因为它可以根据需要动态地创建实例。因此,在需要重复创建对象的情况下,原型模式是一种非常好的解决方案。