◉◡◉ 您好,欢迎到访伊成个人站!

java设计模式之原型模式

原型模式的介绍

用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。在这里,原型实例指定了要创建的对象的种类。用这种方式创建对象非常高效,根本无须知道对象创建的细节。

这种模式存在的应用场景在于,能够复制当前对象,实现对象数据的克隆。比如:如果一个对象的数据需要经过较高代价的数据库操作,采用原型模式能够较好的缓存当前对象,减少数据库的访问量。

原型模式UML类图

“伊成博客”

模式结构

原型模式包含如下角色:
Prototype:抽象原型类
ConcretePrototype:具体原型类
Client:客户类

举个栗子

在日本动漫《火影忍者》中鸣人有一个忍术叫影分身之术,使用查克拉制造出有实体的分身,它们可以和施术者一样行动战斗,具有独立于施术者本体的意识和一定的抗击打能力,解除后分身的记忆和经验会回到本体。

简言之,就是一个鸣人分身后变成了多个一模一样的鸣人,如同把一个鸣人复制出来了N个鸣人,其实这种场景就是我们所说的原型模式。

“伊成博客”

实例源码

MingRen 原型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 public class MingRen implements Cloneable{
public String name = "鸣人";
public int age = 12;
public String skill = "影分身之术";

public MingRen() {
}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}

@Override
public String toString() {
return "MingRen{" +
"name='" + name + '\'' +
", age=" + age +
", skill='" + skill + '\'' +
'}';
}
}

Client类

1
2
3
4
5
6
7
public static void main(String[] args) throws CloneNotSupportedException {
MingRen mingRen = new MingRen();
MingRen mingRen2 = (MingRen)mingRen.clone();
System.out.println(mingRen);
System.out.println(mingRen2);
System.out.println(mingRen == mingRen2);
}

程序的运行结果如下:

1
2
3
4
5
MingRen{name='鸣人', age=12, skill='影分身之术'}
MingRen{name='鸣人', age=12, skill='影分身之术'}
false

Process finished with exit code 0

由以上源码我们可以得知,核心就是类图中的原型类。原型类需要具备以下两个条件:
实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。
重写Object类中的clone方法。默认是浅拷贝。

浅拷贝和深拷贝的说明,就不展开聊了,可参考下文了解。
点击了解 java对象的浅克隆和深克隆

原型模式的优缺点

优点:
1.快速创建复杂对象实例,同时也提高了效率。
2.不用重新初始化对象,而是动态获得对象运行时的状态。
3.如果原始对象发生变化(增加或减少字段)其它克隆对象也会发生相应变化,无需修改代码。

缺点:
1.必须实现Cloneable接口。
2.实现深克隆的时候可能需要比较复杂的代码。
3.需要为每一个类配备一个克隆方法,这对全新的类来说不是很难,但对已有的类进行改造时,需要修改其源代码,违背了 ocp 原则。

原型模式使用案例

1、Spring 中原型 bean 的创建,使用到了原型设计模式。
“伊成博客”

Tips:
原型模式也叫克隆模式!


The end.

支付宝打赏 微信打赏