定义:原型(Prototype)模式的定义如下:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。例如,Windows 操作系统的安装通常较耗时,如果复制就快了很多。
优点:
- Java 自带的原型模式基于内存二进制流的复制,在性能上比直接 new 一个对象更加优良。
- 可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作。
缺点:
- 需要为每一个类都配置一个 clone 方法
- clone 方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则。
- 当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来会比较麻烦。因此,深克隆、浅克隆需要运用得当。
实现方法:
- 实现Cloneable接口
重写clone()方法(clone是Object类的方法) ```java public class Sheep implements Cloneable{
private String name ;
private int age ;
private Color color;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Color getColor() {
return color;
}
@Override public String toString() {
return "Sheep["+this.hashCode()+"]{" +
"name='" + name + '\'' +
", age=" + age +
", color=" + color +
'}';
}
public void setColor(Color color) {
this.color = color;
}
// 浅克隆
@Override
protected Object clone(){
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
**扩展:**
> 浅拷贝:复制一个对象,复制它的变量时又两种情况:
> - 基本数据类型时直接将值传递
> - 对象是复制的引用值
>
深拷贝:也会将其里面的对象复制一份。
上面那方式就是浅拷贝:
```java
public class Color implements Cloneable{
private String name ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Color(String name) {
this.name = name;
}
@Override
public String toString() {
return "Color{" +
"name='" + name + '\'' +
'}';
}
@Override
protected Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
public class Client {
public static void main(String[] args) {
Sheep sheep = new Sheep();
sheep.setName("喜羊羊");
sheep.setAge(3);
Color color = new Color("黑色");
sheep.setColor(color);
Sheep sheep1 = (Sheep) sheep.clone();
System.out.println(sheep);
System.out.println(sheep1);
System.out.println("-------------------------------");
sheep1.setAge(4);
sheep1.setName("美羊羊");
color.setName("白色");
System.out.println(sheep);
System.out.println(sheep1);
}
}
此时打印结果:
深拷贝:
有两种方式:
将里面的对象在复制一遍
// 深克隆
@Override
protected Object clone(){
Sheep sheep = null ;
try {
sheep = (Sheep) super.clone();
sheep.color = (Color) color.clone();
return sheep;
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
此时打印结果:
利用序列化来复制对象(推荐) ```java // 深克隆 序列化 @Override protected Object clone() {
Sheep sheep = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
try {
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this);
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
return ois.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
ois.close();
bis.close();
oos.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
```
此时打印的结果:
可以发现两种方法都可以实现对对象内部的对象的拷贝。