设计模式之原型模式
前言
原型模式(Prototype),又称为克隆模式,属于创建型设计模式,也就是说,原型模式也是用于创建对象用的,跟单例模式、工厂模式、建造者模式这些的主要用途是一致的,不过侧重点不同,原型模式的侧重点是:当对象的创建比较耗时的时候,多次使用new来创建对象所带来的消耗就会比较大,这个时候使用原型模式就是一种比较好的方法了。使用原型模式创建出来的对象是原来对象的拷贝,也就是说,创建之后两者在未进行任何操作的时候,两个对象的状态是一样的。
原型模式的具体实现
模式模式的使用比较简单,只需要为其实现一个Clonable接口,并且提供一个对外访问的方法即可,具体如下所示:
public class Student implements Cloneable{
private String name;
private int age;
private Date birthday;
// 这里省略了相应的set、get方法
/**
* 对外的方法,用于提供单前对象的克隆操作
*/
public Student clone() throws CloneNotSupportedException {
return (Student) super.clone();
}
}
这样,当我们需要多次创建学生对象的时候,只需要调用第一个创建的Student对象的clone()方法即可了,具体如下所示:
public class PrototypeTest {
public static void main(String[] args) {
Student student = new Student();
student.setAge(22);
student.setName("xuhuanfeng");
System.out.println(student);
try {
Student student1 = student.clone();
System.out.println(student1);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
对应的输出内容如下所示:
cn.xuhuanfeng.designpattern.prototype.Student@1b6d3586
cn.xuhuanfeng.designpattern.prototype.Student@4554617c
从上面的结果可以看出,通过克隆方法所创建出来的对象是新的对象。
不过上面这种创建方式是有问题的,因为其中包含了一个birthday属性,该属性是Date的一个对象,而Date对象是可以改变的,也就是说,当我们改变student对象的birthday的时候,student1的birthday也会同样被改变,原因在于,这两个对象指向同一个Date对象birthday,这也就是所谓的浅拷贝。
显然,这不是我们所期待的,我们希望的是一个Student对象有自己的birthday,不管Student对象是怎么创建出来的,所以,我们需要对上面的内容进行一个小小的改动,如下代码所示:
public Student clone() throws CloneNotSupportedException {
Student student = (Student) super.clone();
student.birthday = (Date) this.birthday.clone();// 注意这里
return student;
}
上面改动的内容非常小,但是效果却非常显著,主要的思想就是,把一个对象中的所有的可变类型的属性全部进行一次拷贝,这样,新的对象就拥有了自己的独立的属性了。
总结
本小节主要学习了原型模式,包括了原型模式的基本原理以及原型模式与其他创建者模式的区别,并且通过一个小案例实现了原型模式,设计模式的学习之路还在继续。