设计模式——原型模式

一、介绍

    原型模式适用于创建重复对象,同时也能保证性能。该模式是创建对象的最佳方式。

二、实现

    需要创建的对象要实现Cloneable接口,并且重写clone方法。

三、实例

public class Student implements Cloneable{

    private String name;
    private Integer age;
    private Integer height;
    private Integer weight;

    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 Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age) &&
                Objects.equals(height, student.height) &&
                Objects.equals(weight, student.weight);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age, height, weight);
    }
}
public static void main(String[] args){
        try {
            Student student = new Student();
            student.setName("张三");
            student.setAge(20);
            student.setHeight(180);
            student.setWeight(65);
            Student student1 = (Student) student.clone();
            System.out.println(student.equals(student1));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }

    测试输出结果为:true

    可以看到克隆之后的两个对象是完全相等的。

    如果在属性中加一个引用类型,当克隆之后修改其中一个对象的引用类型的值,其余的都会改变,这是应为在克隆时引用不会创建新的对象,而是指向存在的对象的地址,所以才会有更改一个之后其余的对象的引用值也会改变,这也是浅克隆,如果不希望改变就要用深克隆,引用对象也创建一个新的对象。

    以同样上面的例子为例,在属性中添加一个List,我们进行深克隆,深克隆的方法有很多,这里我们就用序列化的方式进行深克隆。

public class Student implements Cloneable, Serializable {

    private String name;
    private Integer age;
    private Integer height;
    private Integer weight;
    private List<String> list;
    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 Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getWeight() {
        return weight;
    }

    public void setWeight(Integer weight) {
        this.weight = weight;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        super.clone();
        Student student = null;
        try{
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream os = new ObjectOutputStream(baos);
            os.writeObject(this);
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream is = new ObjectInputStream(bais);
            student = (Student) is.readObject();
        }catch (Exception e){
            e.printStackTrace();
        }finally {

        }
        return student;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age) &&
                Objects.equals(height, student.height) &&
                Objects.equals(weight, student.weight) &&
                Objects.equals(list, student.list);
    }

    @Override
    public int hashCode() {

        return Objects.hash(name, age, height, weight, list);
    }
}
public static void main(String[] args){
        try {
            Student student = new Student();
            student.setName("张三");
            student.setAge(20);
            student.setHeight(180);
            student.setWeight(65);
            List<String> list = new ArrayList<>();
            list.add("111");
            list.add("222");
            list.add("333");
            student.setList(list);
            Student student1 = (Student) student.clone();
            System.out.println(student.equals(student1));
            student1.getList().remove(1);
            System.out.println(student.getList());
            System.out.println(student1.getList());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    试输出结果为:true

    两个list也不一样,并没有因为改变了其中一个而影响另一个。

四、优点

    1、比new一个对象效率更高,因为它是直接操作的内存中的二进制流。

五、缺点

    1、无法于单例模式结合使用。

    2、深克隆时需要自己实现。





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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值