原型模式
一、原型模式的定义:
原型模式是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象,属于创建型设计模式。
原型模式的核心在于复制原型对象。以系统中已存在的一个对象为原型,直接基于内存二进制流进行复制,不需要再经历耗时的初始化过程(不调用构造函数),性能提升许多。当对象构建过程比较耗时时,可以把当前系统中已存在的对象作为原型,对其进行复制,躲避初始化过程,使新对象的创建时间大大缩短。
二、原型模式的应用场景
你一定遇到过大篇幅的Getter,Setter赋值的场景,例如下面代码:
public class ExamFromVo {
public ExamFromVo copy(){
ExamFromVo examFromVo = new ExamFromVo();
// 剩余时间
vo.setLeaveTime(this.getLeaveTime());
vo.setOrganizationId(this.getOrganizationId());
vo.setId(this.getId());
vo.setUserId(this.getUserId());
vo.setPositionCode(this.getPositionCode());
.....
}
}
上面的代码看上去非常工整,命名非常规范。但是大家觉得这样的代码优雅吗?笔者认为,这样的代码属于纯体力劳动。那原型模式可以为我们大量的规避这种体力劳动,提高开发效率。
三、原型模式的适用场景
- 创建成本比较大(例如,初始化时间长,占用CPU太多,或者占用网络资源太多等),需要优化资源。
- 创建一个对象需要繁琐的数据准备或者访问权限,需要提高性能或者安全性。
- 系统中大量使用,且各个调用者都需要给他的属性重新赋值。
在Spring中,原型模式应用非常广泛,例如:scope="prototype"、JSON.parseObject(),都是原型模式的具体应用。
四、原型模式的UML类图
由上图可以看出,圆形模式主要包含了三个角色。
1. 客户:客户类提出创建对象的请求。
2. 抽象原型:规定复制接口。
3. 具体原型:被复制的对象。
注:不是通过new关键字而是通过对象复制来实现创建对象的模式,称作原型模式。
五、原型模式的通用写法
package com.demo.prototype;
public class Prototype {
public static void main(String[] args) {
// 创建原型对象
ContretePrototypeA contretePrototypeA = new ContretePrototypeA("original-A");
System.out.println(contretePrototypeA);
// 复制原型对象
ContretePrototypeA clonePrototypeA = contretePrototypeA.clone();
clonePrototypeA.desc = "clone - A";
System.out.println(clonePrototypeA);
// 创建原型对象
ContretePrototypeB contretePrototypeB = new ContretePrototypeB("original-B");
ContretePrototypeB clonePrototypeB = contretePrototypeB.clone();
System.out.println(clonePrototypeB);
}
// 抽象原型
interface IPrototype<T>{
T clone();
}
// 具体原型
static class ContretePrototypeB implements IPrototype<ContretePrototypeB> {
private String desc;
public ContretePrototypeB(String desc) {
this.desc = desc;
}
@Override
public ContretePrototypeB clone() {
return new ContretePrototypeB(this.desc);
}
@Override
public String toString() {
return "ContretePrototypeB{" +
"desc='" + desc + ''' +
'}';
}
}
// 具体原型
static class ContretePrototypeA implements IPrototype<ContretePrototypeA>{
private String desc;
public ContretePrototypeA(String desc) {
this.desc = desc;
}
@Override
public ContretePrototypeA clone() {
return new ContretePrototypeA(this.desc);
}
@Override
public String toString() {
return "ContretePrototypeA{" +
"desc='" + desc + ''' +
'}';
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。