设计模式之原型模式(创建型模式)

简介
原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

模式结构
由于 Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单,只需要实现Cloneable接口并重写clone()方法

  • 模式的结构
  1. 抽象原型类:规定了具体原型对象必须实现的接口。
  2. 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  3. 访问类:使用具体原型类中的 clone() 方法来复制新的对象。
  • 模式的实现
    原型模式的克隆分为浅克隆和深克隆,Java 中的 Object 类提供了浅克隆的 clone() 方法,具体原型类只要实现 Cloneable 接口就可实现对象的浅克隆,这里的 Cloneable 接口就是抽象原型类。
public class PrototypePattern{
    public static void main(String[] args) throws Exception{
        Prototype prototype=new Prototype("zx",25);
        Prototype clone=(Prototype) prototype.clone();
        clone.setAge(28);
        System.out.println(prototype);
        System.out.println(clone);
    }
}
//具体原型类
@Data
class Prototype implements Cloneable {
    private String name;
    private Integer age;
    Prototype() {}
    public Prototype(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("具体原型创建成功!");
    }

    public Object clone() throws CloneNotSupportedException{
        System.out.println("具体原型复制成功!");
        return (Prototype)super.clone();
    }
}

在这里插入图片描述

  • 优点
  1. 性能优良:原型模式是在内存二进制流的拷贝,要比new一个对象性能好很多,特别是在一个循环体类产生大量对象的时候更加明显。
  2. 逃避构造函数的约束:这是优缺点共存的一点,直接在内存中拷贝,构造函数是不会执行的
  • 适用场景
  1. 资源初始化场景:类初始化需要消耗非常多的资源的时候。
  2. 性能和安全要求的场景:通过new产生一个对象需要非常繁琐的数据准备和访问权限的时候。
  3. 一个对象多个修改者的场景:一个对象需要提供给其他对象访问,而各个调用者可能都需要修改其值时考虑使用。

实际项目中原型模式很少单独出现,一般和工厂模式一起出现,通过clone方法创建一个对象,然后由工厂方法提供给调用者。

深拷贝、浅拷贝

  • 浅克隆
    创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。Java中的浅复制通常使用clone()方式完成。
  • 深克隆
    创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。Java中通过对象的序列化和反序列化实现克隆

序列化实现深克隆

 @SuppressWarnings("unchecked")
    public static <T extends Serializable> T clone(T obj) throws Exception {
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        oos.writeObject(obj);

        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();

        // 说明:调用ByteArrayInputStream或ByteArrayOutputStream对象的close方法没有任何意义
        // 这两个基于内存的流只要垃圾回收器清理对象就能够释放资源,这一点不同于对外部资源(如文件流)的释放
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值