定义
用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
原型模式会要求对象实现一个可以“克隆”自身的接口。这样就可以通过拷贝或者克隆一个实例对象本身来创建一个新的实例。如果把这个方法定义在接口上,看起来就像是通过接口创建了新的接口对象。
结构说明
- Prototype:声明一个克隆自身的接口,用来约束想要克隆自身的类,要求它们都要实现这里定义的克隆方法。
- ConcretePrototype:实现Prototype接口的类,这些类真正实现了克隆自身的功能。
- Client:使用原型的客户端,首先要获取到原型实例对象,然后通过原型实例克隆自身来创建新的对象
代码示例
/**
* @Description 声明一个克隆自身的接口
* @Author guantong
* @Date 2020/10/20 13:51
* @Version 1.0
*/
public interface Prototype {
Prototype clone();
}
/**
* @Description 克隆的具体实现类
* @Author guantong
* @Date 2020/10/20 13:52
* @Version 1.0
*/
public class ConcretePrototype1 implements Prototype {
@Override
public Prototype clone() {
// 创建一个自身的对象
return new ConcretePrototype1();
}
}
/**
* @Description 克隆的具体实现类
* @Author guantong
* @Date 2020/10/20 13:53
* @Version 1.0
*/
public class ConcretePrototype2 implements Prototype {
@Override
public Prototype clone() {
// 创建一个自身的实例
return new ConcretePrototype2();
}
}
/**
* @Description 使用原型的客户端
* @Author guantong
* @Date 2020/10/20 13:54
* @Version 1.0
*/
public class Client {
/**
* 原型接口对象
*/
private Prototype prototype;
/**
* 通过构造方法传入需要使用的原型接口对象实例
* @param prototype
*/
public Client(Prototype prototype){
this.prototype = prototype;
}
/**
* 执行某个操作
*/
public void operation(){
// 通过克隆方法创建原型对象
Prototype newPrototype = this.prototype.clone();
}
}
原型模式的功能
原型模式的功能实际上包含两个方面:
- 一个是通过克隆来创建新的对象实例
- 另一个是为克隆出来的新的对象实例赋予原型实例属性的值
原型模式要实现的主要功能就是:通过克隆来创建新的对象实例。一般来讲,新创建出来的实例的数据是和原型实例一样的。但是具体如何实现克隆,需要程序自行实现,原型模式并没有统一的要求和实现算法。
原型与new
原型模式从某种意义上来说,就像是new操作,在前面的例子实现中,克隆方法就是使用new来实现的。但请注意,只是“类似于new”而不是“就是new”。克隆方法和new操作最明显的不同就在于:new一个对象实例,其属性是没有值的,或者说只有默认值。而通过克隆创建出来的对象实例,通常属性时有值的,其值就是原型对象实例在克隆时,其本身的属性值。
原型实例和克隆的实例
原型实例和克隆出来的实例,本质上是不同的实例,克隆完成之后,它们之间是没有关联的。如果克隆完成之后,克隆出来的对象实例其属性值发生了变化,其原型实例对象的属性值是不会发生变化的,也就是说克隆出来的对象实例的变化时不会影响其原型实例对象。
原型模式的优缺点
优点
1、对客户端隐藏具体的实现类型 原型模式的客户端只知道原型接口的类型,并不知道具体的实现类型。从而减少了客户端对这些具体实现类型的依赖
2、在运行时动态改变具体的实现类型 原型模式可以在运行期间,可以由客户来注册符合原型接口的实现类型,也可以动态地改变具体的实现类型,看起来接口没有任何变化,但其实运行的已经是另外一个类的实例了。因为克隆一个原型就类似于实例化一个类。
缺点
原型模式的最大缺点在于,每个原型的子类都必须实现clone的操作,尤其是在包含引用类型的对象时,clone方法会比较麻烦,必须要递归让所有的相关对象都要正确地实现克隆
思考
原型模式的本质
原型模式的本质:克隆并生成对象
克隆时手段,目的是生成新的对象实例,正式因为原型的目的是为了生成新的对象实例,故原型模式被归类的创建型。
原型模式也可以用来解决“只知接口而不知实现的问题”,使用原型模式,可以出现一种独特的“接口造接口”的景象,这在面向接口编程中很有用。同样的功能也可以考虑使用工厂来实现。
另外,原型模式的重心还是在创建新的对象实例,至于创建出来的对象实例的属性值是否与原型对象一致,则没有明确的强制规定,只不过就目前大多数的场景中,都是一致的。
何时使用原型模式
- 如果一个系统想要独立于它想要使用的对象时,可以使用原型模式。让系统只面向接口编程,在系统需要新的对象的时候,可以通过克隆来得到。
- 如果需要实例化的类是在运行期动态指定的,可以使用原型模式,通过克隆来得到需要的实例。