GOF23设计模式之原型模式

GOF23设计模式之原型模式

1)通过 new 产生一个对象需要飞船繁琐的数据准备或访问权限,则可以使用原型模式。

2)就算 java 中的克隆技术,以某个对象为原型,复制出新的对象。显然,新的对象具备原型对象的特点

3)优势在于效率高(直接克隆,避免了重新执行构造过程步骤)

4)克隆类似于 new ,但是不同于 new。new 创建新的对象属性采用的是默认值。克隆出的对象的属性值完全和原型对象相同,并且克隆出的新对象改变不会影响原型对象。然后,再修改克隆对象的值。

实现:

1)Cloneable 接口和 clone 方法

2)Prototype 模式中实现起来最困难的地方就算内存复制操作,所幸在 Java 中提供了 clone()方法替我们做了绝大部分的事情。

package cn.taosir.design.create.prototype;

import java.util.Date;

public class Sheep implements Cloneable {
    private String name;
    private Date birthday;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //直接调用object的clone方法
        Object obj=super.clone();
        return obj;
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public Date getBirthday() {return birthday;}
    public void setBirthday(Date birthday) {this.birthday = birthday;}
    public Sheep(String name, Date birthday) {
        super();
        this.name = name;
        this.birthday = birthday;
    }
    
    public static void main(String[] args) throws CloneNotSupportedException {
        Sheep s1=new Sheep("taosir", new Date());
        Sheep s2=(Sheep)s1.clone();
        System.out.println(s1==s2);
    }
}

注意:上面的代码为浅克隆,其中的引用类型字段(birthday)引用的是同一个对象

package cn.taosir.design.create.prototype;

import java.util.Date;

public class Sheep2 implements Cloneable {
    private String name;
    private Date birthday;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //直接调用object的clone方法
        Object obj=super.clone();
        //添加如下代码实现深复制
        Sheep2 s=(Sheep2)obj;
        s.birthday=(Date)this.birthday.clone();
        return obj;
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public Date getBirthday() {return birthday;}
    public void setBirthday(Date birthday) {this.birthday = birthday;}
    public Sheep2(String name, Date birthday) {
        super();
        this.name = name;
        this.birthday = birthday;
    }
    
    public static void main(String[] args) throws CloneNotSupportedException {
        Sheep2 s1=new Sheep2("taosir", new Date());
        Sheep2 s2=(Sheep2)s1.clone();
        System.out.println(s1==s2);
    }
}

深克隆的方式有很多,自行实现即可,如上 

下面也提供使用序列化和反序列化实现深复制的代码

package cn.taosir.design.create.prototype;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;

public class Sheep3 implements Serializable,Cloneable {
    private String name;
    private Date birthday;
    @Override
    protected Object clone() throws CloneNotSupportedException {
        //直接调用object的clone方法
        Object obj=super.clone();
        return obj;
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public Date getBirthday() {return birthday;}
    public void setBirthday(Date birthday) {this.birthday = birthday;}
    public Sheep3(String name, Date birthday) {
        super();
        this.name = name;
        this.birthday = birthday;
    }
    
    public static void main(String[] args) throws Exception {
        Sheep3 s1=new Sheep3("taosir", new Date(321321321));
        System.out.println("s1的创建时间:"+s1.getBirthday());
        
//        Sheep3 s2=(Sheep3)s1.clone();
//        System.out.println("s2的创建时间:"+s2.getBirthday());
//        System.out.println(s1==s2);
        
        //使用序列化和反序列化实现深复制
        ByteArrayOutputStream bos=new ByteArrayOutputStream();
        ObjectOutputStream oos=new ObjectOutputStream(bos);
        oos.writeObject(s1);
        byte[] bytes=bos.toByteArray();
        
        ByteArrayInputStream bis=new ByteArrayInputStream(bytes);
        ObjectInputStream ois=new ObjectInputStream(bis);
        Sheep3 s2=(Sheep3)ois.readObject();
        
        s2.setBirthday(new Date());
        System.out.println("s1的时间:"+s1.getBirthday());
        System.out.println("s2的时间:"+s2.getBirthday());
    }
}

 

posted @ 2019-03-10 23:39  涛先森の日常  阅读(347)  评论(0编辑  收藏  举报