课程咨询 :0592-5903858 QQ:1079585464

厦门达内java培训

厦门Java培训 > 达内新闻 > 达内:Java设计模式中的原型模式
  • 达内:Java设计模式中的原型模式

    发布:厦门Java培训      来源:慕课网      时间:2016-04-07


  •     厦门达内java培训专家讲一下Java设计模式中的原型模式。

    一、原型模式
     
        原型模式与构造器模式、单例模式、工厂方法模式、抽象工厂模式一样,都属于创建型模式。原型模式理解起来,相对简单,来看下其定义:

        用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

        原型模式的实例的拷贝包括浅复制和深复制:

        浅复制:将一个对象复制后,其基本数据类型的变量都会重新创建,而引用类型的变量指向的还是原对象所指向的,也就是指向的内存堆地址没变。

        深复制:将一个对象复制后,不论是基本数据类型还是引用类型,都是重新创建的。

        从以上可以看出,浅复制中的引用类型只是复制了变量的值,其地址仍然没变;而深复制完全复制了变量,复制后变量地址会有所变化。

        有一个消息类,其属性及方法声明如下:


    public class Message implements Cloneable, Serializable {
        private String name;  //消息名称
        private String size;  //消息大小
        private int type;     //消息类型
        private Date date;    //创建日期

        public static final int TEXT = 0x01;
        public static final int PIC = 0x02;
        public static final int VIDEO = 0x03;
        public static final int MIX = 0x04;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getSize() {
            return size;
        }

        public void setSize(String size) {
            this.size = size;
        }

        public int getType() {
            return type;
        }

        public void setType(int type) {
            this.type = type;
        }

        public Date getDate() {
            return date;
        }

        public void setDate(Date date) {
            this.date = date;
        }

        public Message clone() throws CloneNotSupportedException {
            return (Message) super.clone();
        }

        public Message deepClone() throws CloneNotSupportedException,
                IOException, ClassNotFoundException {
            //把对象写入到字节流中
            ByteArrayOutputStream baos =new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);

            //把字节流转化为对象
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            return (Message) ois.readObject();
        }

        @Override
        public String toString() {
            String tos = "name[" + name + "],size[" + size +
                    "],type[" + type + "],date[" + date + "]";
            return tos;
        }

        public static void main(String[] a) {
            Message msg = new Message();
            msg.setName("好友消息");
            msg.setSize("123KB");
            msg.setType(Message.TEXT);
            msg.setDate(new Date());

            System.out.println("msg:" + msg.toString());

            try {
                Message cloneMsg = msg.clone();

                System.out.println("msg:" + msg.toString());
                System.out.println("cloneMsg:" + cloneMsg.toString());

                System.out.println(cloneMsg.getDate() == msg.getDate());
                System.out.println(cloneMsg.getName() == msg.getName());
                System.out.println(cloneMsg.getType() == msg.getType());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


        通过实现Cloneable接口,java默认的实现方式是浅复制,而非深复制。由于Object并没有实现Cloneable接口,所以子类必须实现Cloneable,并调用基类的clone方法才能实现浅复制。

        要实现深复制,Message类需要实现序列化,通过对象流与字节流之间的转化,达到深复制的目的。

        Message类中的deepClone方法就是深复制的实现。

        以上main方法的执行结果如下:


    msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]
    msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]
    cloneMsg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:47:56 CST 2016]
    true
    true
    true


        说明,浅复制只是复制了引用类型的值,并没有改变其地址,指向的仍然是原对象的变量地址。

        在main方法中调用deepClone方法:


      public static void main(String[] a) {
            ......

            Message cloneMsg = msg.deepClone();

            ......
        }


        最后的输出结果如下:


    msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]
    msg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]
    cloneMsg:name[好友消息],size[123KB],type[1],date[Tue Apr 05 17:54:39 CST 2016]
    false
    false
    true


        可以看出,深复制下,引用类型变成了完全的复制,所有的引用类型地址都变化了。


    二、jdk中的原型模式
     
        jdk中大部分类都提供了克隆的方法,比如Date类:


    public class Date
        implements java.io.Serializable, Cloneable, Comparable<Date>
    {
       public Object clone() {
            Date d = null;
            try {
                d = (Date)super.clone();
                if (cdate != null) {
                    d.cdate = (BaseCalendar.Date) cdate.clone();
                }
            } catch (CloneNotSupportedException e) {} // Won't happen
            return d;
        }
    }



    本文由慕课网 ifynn原创,原文链接: http://www.imooc.com/article/6233
    推荐文章

上一篇:2016达内春季人才招聘会火爆来袭

下一篇:达内:Java设计模式中的构造器模式

最新开班日期  |  更多

Java--大数据周末班

Java--大数据周末班

开班日期:每周一

Java--大数据全日制班

Java--大数据全日制班

开班日期:每周一

Java--零基础周末班

Java--零基础周末班

开班日期:每周一

Java--零基础全日制班

Java--零基础全日制班

开班日期:每周一

  • 地址:厦门软件园二期望海路59号之一401达内科技
  • 课程培训电话:0592-5903858 QQ:1079585464     全国服务监督电话:400-827-0010
  • 服务邮箱 ts@tedu.cn
  • 2001-2016 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56