设计模式之原型模式

设计模式之原型模式


什么是原型模式

原型模式:通过new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式
就是java中的克隆技术,以某个对象为原型,复制出新的对象,显新的对象具有原型对象的特点
克隆,类似于new,但是不同于new new创建的对象属性采取默认值,克隆出的对象属性和原型对象相同,并且克隆出的新的对象改变不会影响原型对象。
原型模式的实现,Cloneable接口和clone方法


原型模式怎么使用

我们以克隆羊多利为例实现浅复制

import java.util.Date;

public class Sheep implements Cloneable {
    private String name;
    private Date brithday;

    public Sheep(String name, Date brithday) {
        super();
        this.name = name;
        this.brithday = brithday;
    }

    public Sheep() {
        super();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object object = super.clone(); // 调用object的clone 实现克隆
        return object;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the brithday
     */
    public Date getBrithday() {
        return brithday;
    }

    /**
     * @param brithday
     *            the brithday to set
     */
    public void setBrithday(Date brithday) {
        this.brithday = brithday;
    }
}
package Prototype;

import java.util.Date;

/**
 * 原型模式,克隆模式(浅克隆)
 */
public class Client {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        Sheep sheep = new Sheep("多利的原型", date);
        Sheep sheep2 = (Sheep) sheep.clone();

        System.out.println(sheep);
        System.out.println(sheep.getName());
        System.out.println(sheep.getBrithday());

        date.setTime(43243151543252L);
        System.out.println(sheep.getBrithday());

        sheep2.setName("多利");
        System.out.println();
        System.out.println("---------克隆后--------------");
        System.out.println(sheep2);
        System.out.println(sheep2.getName());
        System.out.println(sheep2.getBrithday());

    }
}
//Prototype.Sheep@2a139a55
//多利的原型
//Fri Apr 21 10:04:39 GMT+08:00 2017
//Wed Apr 27 18:32:23 GMT+08:00 3340
//
//---------克隆后--------------
//Prototype.Sheep@70dea4e
//多利
//Wed Apr 27 18:32:23 GMT+08:00 3340


//浅复制共用一个date对象,当date对象修改时克隆对象也被修改

深复制(将属性也进行克隆)

package Prototype;

import java.util.Date;

public class Sheep2 implements Cloneable{
    private String name;
    private Date brithday;

    public Sheep2(String name, Date brithday) {
        super();
        this.name = name;
        this.brithday = brithday;
    }

    public Sheep2() {
        super();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object object = super.clone(); // 调用object的clone 实现克隆
        Sheep2 sheep2 = (Sheep2) object;
        sheep2.brithday = (Date) this.brithday.clone();//将date进行可克隆
        return object;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the brithday
     */
    public Date getBrithday() {
        return brithday;
    }

    /**
     * @param brithday
     *            the brithday to set
     */
    public void setBrithday(Date brithday) {
        this.brithday = brithday;
    }
}
package Prototype;

import java.util.Date;

/**
 *  原型模式,(深复制)
 */
public class Client2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date();
        Sheep2 sheep = new Sheep2("多利的原型", date);
        Sheep2 sheep2 = (Sheep2) sheep.clone();

        System.out.println(sheep);
        System.out.println(sheep.getName());
        System.out.println(sheep.getBrithday());

        date.setTime(43243151543252L);
        System.out.println(sheep.getBrithday());

        sheep2.setName("多利");
        System.out.println();
        System.out.println("---------克隆后--------------");
        System.out.println(sheep2);
        System.out.println(sheep2.getName());
        System.out.println(sheep2.getBrithday());
    }

}
//Prototype.Sheep2@2a139a55
//多利的原型
//Fri Apr 21 10:13:18 GMT+08:00 2017
//Wed Apr 27 18:32:23 GMT+08:00 3340
//
//---------克隆后--------------
//Prototype.Sheep2@70dea4e
//多利
//Fri Apr 21 10:13:18 GMT+08:00 2017

//深复制,将date属性进行复制,改变date之后克隆对象的date不变,克隆之后为两个date对象

用序列化反序列化实现深克隆

package Prototype;

import java.io.Serializable;
import java.util.Date;

public class Sheep implements Cloneable,Serializable{
    private String name;
    private Date brithday;

    public Sheep(String name, Date brithday) {
        super();
        this.name = name;
        this.brithday = brithday;
    }

    public Sheep() {
        super();
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object object = super.clone(); // 调用object的clone 实现克隆
        return object;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the brithday
     */
    public Date getBrithday() {
        return brithday;
    }

    /**
     * @param brithday
     *            the brithday to set
     */
    public void setBrithday(Date brithday) {
        this.brithday = brithday;
    }
}
package Prototype;

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

public class Client3 {
    public static void main(String[] args) throws Exception {
        Date date = new Date();
        Sheep sheep = new Sheep("多利的原型", date);


        System.out.println(sheep);
        System.out.println(sheep.getName());
        System.out.println(sheep.getBrithday());
        //用序列化和反序列化实现深复制
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(sheep);
        byte[] bytes = bos.toByteArray();


        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);

        Sheep sheep2 = (Sheep) ois.readObject();


        date.setTime(43243151543252L);
        System.out.println(sheep.getBrithday());
        sheep2.setName("多利");
        System.out.println();
        System.out.println("---------克隆后--------------");
        System.out.println(sheep2);
        System.out.println(sheep2.getName());
        System.out.println(sheep2.getBrithday());

    }
}
//Prototype.Sheep@2a139a55
//多利的原型
//Fri Apr 21 10:30:14 GMT+08:00 2017
//Wed Apr 27 18:32:23 GMT+08:00 3340
//
//---------克隆后--------------
//Prototype.Sheep@677327b6
//多利
//Fri Apr 21 10:30:14 GMT+08:00 2017

/**
 *   测试new方式和clone方式创建对象耗时
 *   
 *   如果需要创建多个对象,并且创建的对象比较耗时,可以用原型模式。
 */
public class Client4 {
    public static void main(String[] args) throws CloneNotSupportedException {
        newtest(1000);
        clonetest(1000);
    }

    public static void newtest(int size) {
        long start = System.currentTimeMillis();

        for (int i = 0; i < size; i++) {
            computer c = new computer();
        }

        long end = System.currentTimeMillis();
        System.out.println("new 的方式耗时" + (end - start));
    }

    public static void clonetest(int size) throws CloneNotSupportedException {
        long start = System.currentTimeMillis();

        computer c = new computer();
        for (int i = 0; i < size; i++) {
            computer c2 = (computer) c.clone();
        }

        long end = System.currentTimeMillis();
        System.out.println("clone" + " 的方式耗时" + (end - start));
    }
}

class computer implements Cloneable {
    public computer() {
        try {
            Thread.sleep(10);
            // 模拟创建对象耗时
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

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

}
//new 的方式耗时10188
//clone 的方式耗时10

什么时候用原型模式

开发中常见的场景:
一般和工厂方法模式一起出现,通过克隆的方式创建对象,然后由工厂提供给调用者
Spring的bean的创建就是单例模式和克隆模式。

创建型模式:都是用来创建对象的

单利模式:保证类只有一个对象,并且提供一个访问该实例的全局访问点。

工厂模式:
简单工厂模式:用来生产同一等级结构的任意产品(对于新的产品,秀要修改已有的代码)
工厂方法模式:用于生产同一等级结构中的固定产品。(支持增加新产品)
抽象工厂模式:用来生产不同产品族的全部产品。(对于增加新的产品无能为力)
建造者模式:
分离对象的子组建的单独构造(由builder负责)和装配(有Director负责)。从而可以构造出复杂的对象。
原型模式 :
通过new产生一个需要非常繁琐的数据准备或者访问权限,可以使用原型模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值