原型模式
定义
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
优缺点
优点:
Java自带原型模式基于内存二进制流的复制,在性能上比直接new一个对象更加优良;
可以使用深克隆方式保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化创建对象的过程,以便在需要的时候,可以辅助实现撤销;
缺点:
需要为每一个类配置clone方法;
clone方法位于类的内部,当对已有类进行改造时,需要修改代码,违背了开闭原则;
当实现深克隆时,需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来比较麻烦。因此,深克隆和浅克隆需要运用得当。
类图
原型模式的克隆分为浅克隆和深克隆。
- 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
- 深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
/**
* @description: 原型模式
* @author: Suy
* @createDate: 2021/4/10 16:44
*/
public class Prototype implements Cloneable{
@Override
protected Object clone() throws CloneNotSupportedException {
System.out.println("复制模型成功");
return (Prototype)super.clone();
}
}
/**
* @description: 原型测试类
* @author: Suy
* @createDate: 2021/4/10 17:10
*/
public class PrototypeTest {
public static void main(String[] args) throws CloneNotSupportedException {
Prototype prototype = new Prototype();
Prototype prototype2 = (Prototype)prototype.clone();
System.out.println("prototype==prototype2:" + (prototype == prototype2));
//结果为false
}
}
原型模式的应用场景
原型模式通常适用于以下场景:
- 对象之间相同或相似,即只是个别的几个属性不同的时候。
- 创建对象成本较大,例如初始化时间长,占用CPU太多,或者占用网络资源太多等,需要优化资源。
- 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性。
- 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值。
扩展
/**
* @description: 原型模式扩展
* @author: Suy
* @createDate: 2021/4/10 21:43
*/
public class PrototypeShape {
public static void main(String[] args) {
PrototypeManager manager = new PrototypeManager();
Shape circle = manager.getShape("Circle");
circle.countAera();
Shape square = manager.getShape("Square");
square.countAera();
}
}
interface Shape extends Cloneable{
/**
* 克隆
**/
Object clone();
/**
* 计算面积
**/
void countAera();
}
/**
* 圆
**/
class Circle implements Shape{
@Override
public Object clone() {
Circle c = null;
try {
c = (Circle)super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("克隆圆失败");
}
return c;
}
@Override
public void countAera() {
int r = 0;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入圆的半径");
r = scanner.nextInt();
System.out.println("圆的面积是" + (2 * 3.14 * r * r));
}
}
/**
* 正方形
**/
class Square implements Shape{
@Override
public Object clone() {
Square c = null;
try {
c = (Square)super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("克隆正方形失败");
}
return c;
}
@Override
public void countAera() {
int r = 0;
Scanner scanner = new Scanner(System.in);
new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入正方形的边长");
r = scanner.nextInt();
System.out.println("正方形的面积是" + (r * r));
}
}
class PrototypeManager{
private HashMap<String,Shape> maps=new HashMap<String,Shape>();
public PrototypeManager(){
maps.put("Circle",new Circle());
maps.put("Square",new Square());
}
public void addShape(String k,Shape v){
maps.put(k,v);
}
public Shape getShape(String k){
Shape shape = maps.get(k);
return (Shape) shape.clone();
}
}
想获取到更多设计模式内容请关注”爱笑的草帽“的公众号。
你要走,走到灯火通明。