设计模式之原型模式
一、背景
1、解决性能问题
解决对象创建的性能问题。在某些情况下,创建对象的过程是复杂且耗时的,如果需要创建大量相似的对象,就会导致性能下降。原型模式通过复制已有对象的方式来创建新对象,避免了创建对象的耗时操作,提高了性能。
2、对象的创建需要运行时信息
有些对象的创建需要根据运行时的信息进行判断,如果使用传统的创建方式,就需要在代码中加入大量的条件判断语句,使得代码变得复杂且难以维护。而原型模式通过克隆已有对象的方式来创建新对象,避免了条件判断的复杂性。
3、对象的创建过程复杂
有些对象的创建过程包含了多个步骤,例如初始化属性、连接数据库等,如果需要创建大量相似的对象,这些步骤都需要重复执行,导致性能下降。而原型模式通过复制已有对象的方式来创建新对象,避免了这些复杂的初始化过程。
4、对象的创建与使用分离
使用传统的创建方式,对象的创建与使用是紧密耦合的,创建对象的代码必须在使用对象的代码之前。而原型模式将对象的创建与使用分离开来,通过克隆已有对象的方式来创建新对象,使得对象的创建可以在不同的时间和地点进行,提高了系统的灵活性和扩展性。
二、介绍
1、定义
原型模式是一种创建型设计模式,用于创建对象的克隆。它通过复制现有对象的原型来创建新的对象,而无需通过实例化类来创建对象。
2、组成
原型模式包含以下几个角色:
- 抽象原型类:定义具体原型类必须实现的方法。
- 具体原型类:实现抽象原型类的克隆方法,实现对象的复制和克隆。
- 客户端类:使用具体原型类的克隆方法来创建新的对象。
三、代码实现
1、实现Cloneable接口
在Java中,原型模式的实现通常需要实现Cloneable接口,并重写clone()方法来进行对象的复制,同时需要保证对象的成员变量是可拷贝的。
2、代码实现分析
首先,我们创建一个原型类Person ,包含一个方法clone():
java
package org.storemanage.regestercenter.prototypemode;
/**
* @CreateTime: 2024-08-28
* @Description: 原型人
* @Version: 1.0
* @Author: hkf
*/
public class Person implements Cloneable {
private String name;
public Person(String personName) {
this.name = personName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void say(){
System.out.println("说话声音真大!!!");
}
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
然后,我们创建具体原型类PersonTest ,实现Person:
java
package org.storemanage.regestercenter.prototypemode;
/**
* @CreateTime: 2024-08-29
* @Description: 测试类
* @Version: 1.0
* @Author: hkf
*/
public class PersonTest {
public static void main(String[] args) throws CloneNotSupportedException {
//创建相同的对象
for (int i = 0; i < 2; i++) {
Person ps = new Person("王麻子");
System.out.println("王麻子的地址为:"+ps);
System.out.println(ps.getName());
}
//原型模式创建对象
Person person1 = new Person("张三");
Person person2 = (Person) person1.clone();
System.err.println("person1的人类地址为:" + person1);
System.err.println("person2的人类地址为:" + person2);
System.out.println("person1的人类名称为:" + person1.getName());
System.out.println("person2的人类名称为:" + person2.getName());
person1.setName("李四");
System.out.println("设置过值person1的人类名称为:" + person1);
System.err.println("设置过值person2的人类名称为:" + person2);
System.out.println("person1的人类名称为:" + person1.getName());
System.err.println("person2的人类名称为:" + person2.getName());
}
}
结果如下
java
王麻子的地址为:org.storemanage.regestercenter.prototypemode.Person@52af6cff
王麻子
王麻子的地址为:org.storemanage.regestercenter.prototypemode.Person@735b478
王麻子
person1的人类名称为:张三
person2的人类名称为:张三
设置过值person1的人类名称为:org.storemanage.regestercenter.prototypemode.Person@2096442d
person1的人类名称为:李四
person1的人类地址为:org.storemanage.regestercenter.prototypemode.Person@2096442d
person2的人类地址为:org.storemanage.regestercenter.prototypemode.Person@9f70c54
设置过值person2的人类名称为:org.storemanage.regestercenter.prototypemode.Person@9f70c54
person2的人类名称为:张三
Process finished with exit code 0
在以上示例中,我们通过调用person1的clone()方法,得到了一个克隆的person2对象。然后我们修改person1的name属性,发现person2的name属性并未改变,证明它们是两个独立的对象。
3、注意事项
因为Object是所有类的老大,默认都继承他,clone方法也是Object类提供的,如果不实现CloneAble接口。则会报错,示例如下
java
Exception in thread "main" java.lang.CloneNotSupportedException: org.storemanage.regestercenter.prototypemode.Person
at java.base/java.lang.Object.clone(Native Method)
at org.storemanage.regestercenter.prototypemode.Person.clone(Person.java:32)
at org.storemanage.regestercenter.prototypemode.PersonTest.main(PersonTest.java:25)
Process finished with exit code 1
四、总结
1、实现Cloneable接口
原型模式的实现通常需要实现Cloneable接口,并重写clone()方法来进行对象的复制
2、原型模式的优点包括:
- 在运行时动态生成对象,避免了类的实例化过程,提高了对象的创建效率。
- 可以通过复制现有对象的原型来创建新的对象,而无需知道具体的创建细节。
- 可以通过修改原型对象的属性来创建不同的对象,避免了重复的初始化过程。
3、原型模式的缺点包括:
- 需要实现Cloneable接口,并重写clone()方法,如果对象的成员变量是复杂对象,则需要保证这些对象也是可拷贝的。
- 对象的复制可能会带来一些潜在的问题,例如深拷贝和浅拷贝的区别。
- 原型模式在创建对象时,没有调用类的构造函数,可能会绕过一些必要的初始化过程。
4、运用1
在实际应用中,原型模式常用于创建复杂的对象,尤其是那些需要耗费大量资源或时间的对象。通过原型模式,可以通过复制一个已有的对象来创建新的对象,从而避免了重复的初始化过程,提高了性能和效率。
5、运用2
原型模式是一种创建型设计模式,通过复制现有对象来创建新的对象。它主要解决了创建对象的开销问题,避免了直接创建对象的耗时操作。原型模式基于原型实例的克隆来创建新的对象,即通过克隆原型对象得到一个新的对象。