Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 298|回复: 0

[设计模式学习]学习Prototype设计模式

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-11-4 00:01:10 | 显示全部楼层 |阅读模式
    在软件开发中,有时候可能会需要创建一些特别复杂的对象,如果系统中已经存在同样类型的对象,并且不同的属性个数相差不大的话,用Prototype模式可能是一个理想的选择。 定义:
        用原型实例指定创建物件的种类,并且通过拷贝这些原型创建新的物件。    Prototype 模式允许一个物件再创建另外一个可定制的物件,根本无需知道任何如何创建的细节,工作原理是:通过将一个原型物件传给那个要发动创建的物件,这个要发动创建的物件通过请求原型物件拷贝它们自己来实施创建。 类图如下:
      
       
       
         
       

         
       
      
       
    从图上可以看出,使用方法很简单,只要调用对象的clone方法返回一个新的对象就可以了。但是为什么没有其他新的方法来实现这个模式呢?因为java中的Object提供了clone()方法来实现对象的克隆,所以Prototype模式实现一下子变得很简单. 在这个clone方法中,我们只要调用Object的克隆方法返回一个对象,就可以以最简单的方式实现Prototype模式。 在其他编程语言中,就需要创建一个当前类的新的对象,然后把当前对象本身的各属性的值复制一份给新创建的对象,并且返回新对象即可。
    从上图中的main函数的调用过程来看,也可以很清晰地看出Prototype模式和其他创建型模式的不同:Prototype模式创建对象不是通过new一个类,而是通过一个现有的对象实例来的。

    什么时候应该使用prototype模式呢??
    1.当你要创建的对象与现有运行时对象相似度很大时
    2.为了避免创建类的工厂类导致层次复杂度增加时
    3.当类的实例只有不多的几种状态时(此时需要引进原型管理器)

    Prototype模式常用在一些对象管理器中。这些对象管理器本身一般为单例模式,主要负责对象的创建和返回。由于返回的对象的类型基本上是一致的,而且返回的对象的各项属性大多保持一致,只有极少数属性才需要修改,所以用Prototype无疑是极好的选择。

    需要注意的是:浅拷贝和深拷贝的区别。 简单的讲,浅拷贝就是只对当前对象的直属属性进行复制,如果其属性是基本类型的话,就复制原对象的值;如果其属性是其他对象的话,就复制对象的地址。而深拷贝则是麻烦的多,如果其属性是对象的话,就需要创建一个新的子属性的对象,并且对这个对象的各项属性进行复制,如果子属性还有子属性的话,则需要递归的进行复制操作。 一切就看需求,如果那些属性的值不会被变更的话,那么只需要实现浅拷贝即可;否则,深拷贝就是必须的。












    package com.kingswood.pattern.creational.protoType;  
      
    public interface ProtoType extends Cloneable {  
      
        public Object clone();  
      
    }  [/code]


    ?






    package com.kingswood.pattern.creational.protoType;  
      
    public class ConcreteProtoType implements ProtoType {  
      
        private String propA;  
      
        private String propB;  
      
        public String getPropA() {  
            return propA;  
        }  
      
        public void setPropA(String propA) {  
            this.propA = propA;  
        }  
      
        public String getPropB() {  
            return propB;  
        }  
      
        public void setPropB(String propB) {  
            this.propB = propB;  
        }  
      
        public Object clone(){  
            try {  
                return super.clone();  
            } catch (CloneNotSupportedException e) {  
                return null;  
            }  
        }  
      
    } [/code]


    ?






    package com.kingswood.pattern.creational.protoType;  
      
    import junit.framework.TestCase;  
      
    public class Client extends TestCase {  
      
        public static void testMethod(){  
      
            ConcreteProtoType proto = new ConcreteProtoType();  
      
            proto.setPropA("propA");  
      
            proto.setPropB("propB");  
      
            ConcreteProtoType newProto = (ConcreteProtoType) proto.clone();  
      
            assertNotSame(proto, newProto);  
      
            assertEquals(proto.getPropA(), newProto.getPropA());  
      
            assertEquals(proto.getPropB(), newProto.getPropB());  
      
        }  
    }  [/code]


    ?


    以上样例使用浅克隆方式实现proto type模式,浅克隆无法对对象中包含的其他非java原始类型数据进行复制。如果需要复制其他非java原始类型数据,则需要使用深克隆方式,对象以及其内部所有对象必须实现java.io.Serializable接口,clone方法改写成以下形式:










    public Object clone(){  
      
            try {  
      
                ByteArrayOutputStream ot = new ByteArrayOutputStream();  
      
                ObjectOutputStream oo = new ObjectOutputStream(ot);  
      
                oo.writeObject(this);  
      
                ByteArrayInputStream it = new ByteArrayInputStream(ot.toByteArray());  
      
                ObjectInputStream oi = new ObjectInputStream(it);  
      
                return (oi.readObject());  
      
            } catch (IOException e) {  
                e.printStackTrace();  
                return null;  
            } catch (ClassNotFoundException e) {  
                e.printStackTrace();  
                return null;  
            }  
      
        }  [/code]


      
      
       
       

         
       

         
       
      
    复制代码
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 14:17 , Processed in 0.372719 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表