原型模式的定义(Prototype)
原型模式允许我们向客户端隐藏创建新实例的复杂性。这个概念是复制现有对象而不是从头开始创建新实例,创建新的对象可能包括昂贵的操作。现有对象充当原型并包含对象的状态。只有在需要时,新复制的对象才能更改相同的属性。这种方法节省了昂贵的资源和时间,尤其是在对象创建是一个繁重的过程时。
原型模式是一种创造型设计模式。当对象创建耗时且操作成本高时,需要原型模式,因此我们使用现有对象本身创建对象。从现有对象创建对象的最佳可用方法之一是 clone() 方法. 克隆是实现原型模式的最简单方法。但是,您可以根据自己的业务模型来决定如何复制现有对象。
原型模式的 UML 图
原型模式的代码实现
客户端代码 也就是测试代码
public class TestProtoType {
public static void main(String[] args) {
// 使用克隆出来的对象调用了自己的 doSomething 方法;
Color blueCopy = ColorStore.getColor("blue");
// 使用复制的对象做一些事情
System.out.println("下面的方法是复制的对象调用的...");
blueCopy.doSomething();
Color blackCopy = ColorStore.getColor("black");
// 使用复制的对象做一些事情
System.out.println("下面的方法是复制的对象调用的...");
blackCopy.doSomething();
}
}
抽象类或者接口代码 实现了 clone() 方法
/**
* Color 类实现了 Cloneable 接口,Color 类的实例 可以调用 Object 类里面的 clone() 方法
*/
public abstract class Color implements Cloneable {
protected String colorName;
abstract void doSomething();
@Override
protected Object clone() {
Object clone = null;
try {
clone = super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return clone;
}
}
抽象类中实现了 clone() 方法,继承它的子类都是拥有 clone() 方法的;
需要被克隆的对象所属于的类
BlueColor 颜色类
public class BlueColor extends Color{
public BlueColor() {
this.colorName = "blue";
}
@Override
void doSomething() {
System.out.println("Blue Color do Something");
}
}
BlackColor 颜色类
public class BlackColor extends Color{
public BlackColor() {
this.colorName = "black";
}
@Override
void doSomething() {
System.out.println("black color do Something");
}
}
由于上面的 BlueColor 类以及 BlackColor 都是继承了 Color 类,所以这两个类都是拥有克隆能力的,也就是说,这两个类创建出来的对象是可以被克隆的;
存储被克隆的对象,并且返回克隆对象
/**
* 从存储颜色的类中,进行颜色对象的复制
*/
public class ColorStore {
private static Map<String, Color> colorMap = new HashMap<>();
static {
colorMap.put("blue", new BlueColor());
colorMap.put("black", new BlackColor());
}
public static Color getColor(String colorName) {
// 子类可以强制转换成父类,但是在子类中只能获取父类的字段与方法
// 这里拿到了抽象了父类 Color 的 克隆方法,这个方法是重写了 Object 类的 clone() 方法得到的
return (Color) colorMap.get(colorName).clone();
}
}
原型模式的优点
优点:
1、向客户隐藏了创建对象的复杂性
2、在某些情况下面,复制独享比创建对象的效率更高
缺点:
1、对象复制有的时候是十分复杂的
对象克隆的深拷贝以及浅拷贝
原型模式涉及到了对象的克隆,所以在下面讨论浅拷贝与深拷贝的区别
两者在克隆之后都会产生一个克隆对象,两者不同的是:
浅拷贝中克隆对象与原对象引用地址指向的内存空间是共用的;
深拷贝得到的克隆对象的引用类型和原对象的引用类型是独立的,互不干扰的;
引用拷贝
浅拷贝
深拷贝
小结
本文介绍了原型模式,原型模式主要是用来赋值对象使用的,也就是克隆对象使用的,在克隆对象的时候,被克隆的对象所属于的类是需要拥有 clone() 方法的的,可以通过继承或者实现 Cloneable 接口获得;