Java学习-设计模式-原型模式
概念:
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在原型模式中我们可以利用过一个原型对象来指明我们所要创建对象的类型,然后通过复制这个对象的方法来获得与该对象一模一样的对象实例。这就是原型模式的设计目的。
这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。
浅复制与深复制概念
1.浅复制(浅克隆)
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
2.深复制(深克隆)
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。
理解:
当创建一个对象需要消耗大量资源的时候(不是说这个对象占用很多资源,而是创建这个对象的过程需要消耗大量资源),我们就可以使用原型模式:即从现有的一个对象克隆出一个对象,从而避免了消耗大量资源的创建过程。
关于克隆,这里不详细介绍。有兴趣的可以自己去找博客看一下,有三种方法,这里我只写一种。
没有别的原因,只是因为码字太累了,哎,吐槽下,上完班回来,晚上还要学习一下,贼累。
举例:
就拿之前建造者模式的 “女朋友” 来说。
package Practices.Mode.Prototype_Pattern;
// 1. 首先需要创建一个“女朋友”类
// 定义其属性:比如姓名、年龄、身体、智商等等
// 原型模式需要实现 Cloneable接口,这个接口是一个空接口,里面没有任何需要实现的方法,该接口表示该类能够复制且具体复制的能力
// clone方法是在Object种定义的,而且是protected型的,只有实现了这个接口,才可以在该类的实例上调用clone方法,
// 否则会抛出CloneNotSupportException。
// 然后重写clone() 方法
public class GirlFriend implements Cloneable {
private String body; // 身体属性
private String name; // 名字
private String age; // 年龄
private String IQ; // IQ
// 四个属性的get和set方法
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getIQ() {
return IQ;
}
public void setIQ(String IQ) {
this.IQ = IQ;
}
@Override
public String toString() {
return "GirlFriend{" +
"body='" + body + '\'' +
", name='" + name + '\'' +
", age='" + age + '\'' +
", IQ='" + IQ + '\'' +
'}';
}
// 这里是浅克隆,书写方式基本一致,
// 深克隆也差不多,在这个基础上将属性为应用对象的属性进行一次克隆,这些为引用对象的属性也需要实现浅克隆
public Object clone(){
GirlFriend new_Girl = null;
try {
new_Girl = (GirlFriend) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return new_Girl;
}
}