6.原型模式(Prototype Pattern)

1.介绍

1.1.定义

允许一个对象再创建另外一个可定制的对象,无需知道如何创建的细节。即用原型实例指定创建对象的种类,并且通过拷贝这些原型,创建新的对象。

1.2.工作原理

将原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝它们自己来实施创建。即用基类Object的clone()方法或序列化。

1.3.结构与模式

原型模式包含以下主要角色

  • 抽象原型类:规定了具体原型对象必须实现的接口。
  • 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  • 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

结构图
在这里插入图片描述

2.代码实现

2.1.浅拷贝

public class CloneableSheep implements Cloneable{
    private String name;
    private Integer age;
    private CloneableSheep friend;

    public CloneableSheep(String name, Integer age, CloneableSheep friend) {
        this.name = name;
        this.age = age;
        this.friend = friend;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public CloneableSheep getFriend() {
        return friend;
    }

    public void setFriend(CloneableSheep friend) {
        this.friend = friend;
    }

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

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

客户端

	@Test
    public void test() throws Exception {
        CloneableSheep cs1 = new CloneableSheep("多利", 3, new CloneableSheep("彭彭", 2, null));
        CloneableSheep cs2 = (CloneableSheep) cs1.clone();
        System.out.println("cs1 hashcode:" + cs1.hashCode() + ",cs1 friend hashcode:" + cs1.getFriend().hashCode());
        System.out.println("cs2 hashcode:" + cs2.hashCode() + ",cs2 friend hashcode:" + cs2.getFriend().hashCode());
    }

结果输出

cs1 hashcode:721748895,cs1 friend hashcode:1642534850
cs2 hashcode:1724731843,cs2 friend hashcode:1642534850

2.2.深拷贝

public class SerializableSheep implements Serializable {
    private String name;
    private Integer age;
    private SerializableSheep friend;

    public SerializableSheep(String name, Integer age, SerializableSheep friend) {
        this.name = name;
        this.age = age;
        this.friend = friend;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public SerializableSheep getFriend() {
        return friend;
    }

    public void setFriend(SerializableSheep friend) {
        this.friend = friend;
    }

    public Object clone() {
        ByteArrayOutputStream bos = null;
        ObjectOutputStream oos = null;
        ByteArrayInputStream bis = null;
        ObjectInputStream ois = null;
        try {
            // 序列化
            bos = new ByteArrayOutputStream();
            oos = new ObjectOutputStream(bos);
            oos.writeObject(this);
            // 反序列化
            bis = new ByteArrayInputStream(bos.toByteArray());
            ois = new ObjectInputStream(bis);
            return ois.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                assert bos != null;
                bos.close();
                assert oos != null;
                oos.close();
                assert bis != null;
                bis.close();
                assert ois != null;
                ois.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

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

客户端

	@Test
    public void test() throws Exception {
        SerializableSheep ss1 = new SerializableSheep("山姆", 3, new SerializableSheep("乐乐", 2, null));
        SerializableSheep ss2 = (SerializableSheep) ss1.clone();
        System.out.println("ss1 hashcode:" + ss1.hashCode() + ",ss1 friend hashcode:" + ss1.getFriend().hashCode());
        System.out.println("ss2 hashcode:" + ss2.hashCode() + ",ss2 friend hashcode:" + ss2.getFriend().hashCode());
    }

结果输出

ss1 hashcode:204349222,ss1 friend hashcode:515132998
ss2 hashcode:1279149968,ss2 friend hashcode:59559151

3.应用场景

使用原型模式创建对象比直接new一个对象在性能上要好的多,因为Object类的clone方法是一个本地方法,它直接操作内存中的二进制流,特别是复制大对象时,性能的差别非常明显。
使用原型模式的另一个好处是简化对象的创建,使得创建对象就像我们在编辑文档时的复制粘贴一样简单。

因为以上优点,所以在需要重复地创建相似对象时可以考虑使用原型模式。比如需要在一个循环体内创建对象,假如对象创建过程比较复杂或者循环次数很多的话,使用原型模式不但可以简化创建过程,而且可以使系统的整体性能提高很多。

4.源码分享

github源码地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值