zoukankan      html  css  js  c++  java
  • 设计模式——原型模式

    原型模式的优点:简化对象的创建,使得创建对象就像复制粘贴一样easy。

    使用原型模式创建对象,一般不会调用类的构造方法,Object的clone方法是一个本地方法,直接操作内存中的二进制流,在复制大对象时,性能差别非常明显。

    关于深拷贝与浅拷贝

    浅拷贝 - 拷贝的是值类型以及引用类型的地址

    深拷贝 - 拷贝的是值类型,对于引用类型则是创建一个新的相同的对象,并使用新对象的地址;

    将普通的引用类型的变量赋值给另一个变量,既不属于深拷贝,也不属于浅拷贝!

    Object的clone方法是浅拷贝,值得一提的是,根据实际测试,对于String类型的拷贝,与值类型一样,实际上是拷贝的对象。其他引用类型则拷贝的是对象的地址!

    下面看关于深拷贝与浅拷贝的代码 

    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.factory.method;
    
    import com.pt.factory.abstracted.MountainBike;
    import com.pt.factory.abstracted.RoadBikes;
    
    import java.io.*;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * @description
     * @author panteng
     * @date 17-2-3.
     */
    public class GiantBike extends AbstractBike implements MountainBike, RoadBikes, Cloneable, Serializable {
        /** 自行车种类:山地车 or 公路车 */
        private String type = "";
        /** 自行车ID */
        private int id;
        /** 其他指标 */
        private Map<String, Object> map = new HashMap<String, Object>();
    
        /**
         * @description 展示外观
         * @param
         * @return
         * @throws
         */
        public void showAppearance(){
            System.out.println("我是捷安特自行车,Type=" + this.type);
        }
    
        /**
         * 使用Object默认的为浅拷贝
         * @return
         * @throws CloneNotSupportedException
         */
        public GiantBike clone() throws CloneNotSupportedException{
            return (GiantBike) super.clone();
        }
    
        /**
         * 深拷贝 - 采用串行化的方式
         * @return
         * @throws Exception
         */
        public GiantBike deepClone() throws Exception{
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(this);
    
            ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
            ObjectInputStream oi = new ObjectInputStream(bi);
            return (GiantBike) oi.readObject();
        }
    
        public String getType(){
            return type;
        }
        public void setType(String type){
            this.type = type;
        }
        public int getId(){
            return id;
        }
        public void setId(int id){
            this.id = id;
        }
        public Map<String, Object> getMap(){
            return map;
        }
        public void setMap(Map<String, Object> map){
            this.map = map;
        }
    }
    GiantBike
    @Test
        public void testAssignment(){
            GiantBike bike1 = new GiantBike();
            bike1.setId(1);
            bike1.setType("giant1");
    
            GiantBike bike2 = new GiantBike();
            bike2.setType("giant2");
            bike2.setId(2);
            System.out.println(bike1 == bike2); //false
    
            //赋值既不属于深拷贝 也不属于浅拷贝
            bike2 = bike1;
            System.out.println(bike1 == bike2); //true
    
            bike2.setType("giant2");
            bike2.setId(2); //此处赋值会影响bike1的值
            System.out.println(bike1.getId());
        }
    
        @Test
        public void copyTest() throws Exception{
            GiantBike bike1 = new GiantBike();
            bike1.setId(1);
            bike1.setType("giant1");
            bike1.getMap().put("length", 90);
    
            //测试浅拷贝
            GiantBike bike2 = bike1.clone();
            System.out.println(bike2.getId() + " - " + bike2.getType() + " - " + bike2.getMap().get("length"));
            bike2.setId(2);
            bike2.setType("giant2");
            bike2.getMap().put("length", 92);//在此处获取的map 与 bike1的map是同一个map,说明是浅拷贝
            System.out.println(bike1.getId() + " - " + bike1.getType() + " - " + bike1.getMap().get("length"));
    
            //测试深拷贝
            GiantBike bike3 = bike1.deepClone();
            System.out.println(bike3.getId() + " - " + bike3.getType() + " - " + bike3.getMap().get("length"));
            bike3.setId(3);
            bike3.setType("giant3");
            bike3.getMap().put("length", 93);//在此处获取的map 与 bike1的map不是同一个map,说明是深拷贝
            System.out.println(bike1.getId() + " - " + bike1.getType() + " - " + bike1.getMap().get("length"));
    
    
        }
    测试

    原型模型比较简单,核心类是一个包含复制方法的类,需要实现cloneable接口,其他类继承此类,即可实现克隆!

    /*
     * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
     */
    
    package com.pt.prototype;
    
    import java.io.*;
    
    /**
     * @description
     * @author panteng
     * @date 17-2-6.
     */
    public class PrototypeModle implements Cloneable, Serializable {
        /**
         * 使用Object默认的为浅拷贝
         * @return
         * @throws CloneNotSupportedException
         */
        public PrototypeModle clone() throws CloneNotSupportedException{
            return (PrototypeModle) super.clone();
        }
    
        /**
         * 深拷贝 - 采用串行化的方式
         * @return
         * @throws Exception
         */
        public PrototypeModle deepClone() throws Exception{
            ByteArrayOutputStream bo = new ByteArrayOutputStream();
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(this);
    
            ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
            ObjectInputStream oi = new ObjectInputStream(bi);
            return (PrototypeModle) oi.readObject();
        }
    }
    PrototypeModle
    @Test
        public void copyTest() throws Exception{
            Cells cell1 = new Cells();
            cell1.setId(1);
            cell1.setName("giant1");
            cell1.getMap().put("length", 90);
    
            //测试浅拷贝
            Cells cell2 = (Cells) cell1.clone();
            System.out.println(cell2.getId() + " - " + cell2.getName() + " - " + cell2.getMap().get("length"));
            cell2.setId(2);
            cell2.setName("giant2");
            cell2.getMap().put("length", 92);//在此处获取的map 与 cell1的map是同一个map,说明是浅拷贝
            System.out.println(cell1.getId() + " - " + cell1.getName() + " - " + cell1.getMap().get("length"));
    
            //测试深拷贝
            Cells cell3 = (Cells) cell1.deepClone();
            System.out.println(cell3.getId() + " - " + cell3.getName() + " - " + cell3.getMap().get("length"));
            cell3.setId(3);
            cell3.setName("giant3");
            cell3.getMap().put("length", 93);//在此处获取的map 与 cell1的map不是同一个map,说明是深拷贝
            System.out.println(cell1.getId() + " - " + cell1.getName() + " - " + cell1.getMap().get("length"));
            System.out.println(cell3.getId() + " - " + cell3.getName() + " - " + cell3.getMap().get("length"));
        }
    测试
  • 相关阅读:
    Java 密钥库 证书 公钥 私钥
    Theos小例子
    armbian禁用zram
    常见JS混淆器和特征
    命令行工具收藏
    python中生成器的两段代码
    把mysql数据库从windows迁移到linux系统上的方法
    【转载】使用Flink低级处理函数ProcessFunction
    spark读取压缩文件
    SpringBoot系列——validation参数校验
  • 原文地址:https://www.cnblogs.com/tengpan-cn/p/6369493.html
Copyright © 2011-2022 走看看