设计模式(五)原型模式

 

一.定义与类型

1.定义:指原型实例指定创建对象的种类,并且通过拷贝这些原型对象创建新的对象

不需要知道任何创建的细节,不调用构造函数

2.类型:创建型

二.适用场景

1.类初始化消耗较多的资源

2.new产生的一个对象需要非常繁琐的过程(数据准备、访问权限等)

3.构造函数比较复杂

4.循环体中生产大量对象时

三.优点

1.原型模式性能比直接new一个对象性能高

2.简化创建过程

四.缺点

1.必须配备克隆方法

2.对克隆复杂对象或对克隆出的对象进行复杂改造时,容易引入风险

3.深拷贝、浅拷贝要运用得当

五.扩展

1.深克隆

2.浅克隆

六.代码

package com.caomingyu.autotest.prototype;

import java.util.Date;

public class Pig implements Cloneable {

    private String name;
    private Date birthday;

    public Pig(String name, Date birthday) {
        this.name = name;
        this.birthday = birthday;
    }

    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;
    }

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

    @Override
    public String toString() {
        return "Pig{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}' + super.toString();
    }
}
package com.caomingyu.autotest.prototype;

import java.util.Date;

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date birthday = new Date(0L);
        Pig pig1 = new Pig("佩奇",birthday);
        Pig pig2 = (Pig) pig1.clone();
        System.out.println(pig1);
        System.out.println(pig2);

        pig1.getBirthday().setTime(666666666666L);
        System.out.println(pig1);
        System.out.println(pig2);
    }
}

打印结果

Pig{name='佩奇', birthday=Thu Jan 01 08:00:00 CST 1970}com.caomingyu.autotest.prototype.Pig@2c7b84de
Pig{name='佩奇', birthday=Thu Jan 01 08:00:00 CST 1970}com.caomingyu.autotest.prototype.Pig@3fee733d
Pig{name='佩奇', birthday=Sat Feb 16 09:11:06 CST 1991}com.caomingyu.autotest.prototype.Pig@2c7b84de
Pig{name='佩奇', birthday=Sat Feb 16 09:11:06 CST 1991}com.caomingyu.autotest.prototype.Pig@3fee733d

可以看到修改了pig1的生日,pig2也被修改了,原因是因为默认的clone是浅拷贝,没有拷贝类里面的引用类,两个pig里面的date是同一个对象,所以我们需要修改Pig.java的重写方法clone,修改代码如下:

@Override
    protected Object clone() throws CloneNotSupportedException {
        Pig pig = (Pig) super.clone();
        pig.birthday = (Date) pig.birthday.clone();
        return pig;
    }

七.如何防止原型模式破坏单例模式

1.单例类不要去实现Cloneable接口

2.实现Cloneable接口的clone方法,但是里面不要用默认的super.clone(),而是用单例里面的getInstance获取单例的方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值