设计模式之原型模式

来源:互联网 发布:工程造价软件应用心得 编辑:程序博客网 时间:2024/06/02 04:22

设计模式之原型模式


什么是原型模式

原型模式:通过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产生一个需要非常繁琐的数据准备或者访问权限,可以使用原型模式。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 孕2个月发烧38度怎么办 不知道怀孕喝了止咳糖浆怎么办? 小孩刮头发的备皮刀割住手怎么办? 天梭手表里面的刻度掉了怎么办 国战天下手游帐号丢失怎么办 肺力咳合剂一次喝了50多了怎么办 头孢和藿香正气水一起吃了怎么办 小儿胃蛋自酶合剂吃多了怎么办 刚出生的婴儿很容易被惊醒怎么办 1个多月的宝宝小腿不直怎么办 20个月宝宝腿不直小腿外八怎么办 小孩手青枝骨骨折拆石膏还弯怎么办 宝宝喝柴胡注射剂有不良反应怎么办 九个月宝宝便秘拉不出来怎么办 一岁四个月的宝宝便秘怎么办 热血三国3要塞打不过去怎么办 清香木夏天有黄叶和掉叶怎么办 生完宝宝妊娠纹还在继续疯长怎么办 陌陌不能最小化观看直播视频怎么办 苏州园区公积金密码忘记了怎么办 房产企业申请破产买的房子怎么办 被业务员骗了买了保险怎么办 孩子特别害怕老师严厉的批评怎么办 4k电视看有线电视不清晰怎么办 移动9.9流量4g网用完了怎么办 东方头条验证码已经被注册了怎么办 打王者两个人吵架被夹在中间怎么办 顾客拿过期的食品过来投诉怎么办 老婆总是埋怨我父母我该怎么办? 代款公司如果使用暴力追债怎么办 法院拍卖款分配有疑意怎么办 法院拍卖买到的房子里有户口怎么办 新注册手机邮箱不和电脑同步怎么办 移动4g盒当月流量封顶怎么办 昆仑加油卡密码忘记了怎么办 昆仑银行e盾密码忘记了怎么办 中石化加油卡密码忘记了怎么办 壳牌加油卡密码忘了怎么办 中国石化加油卡密码忘了怎么办 中石化加油卡密码忘了怎么办 中石化加油卡需要密码忘了怎么办