Java设计模式4-原型模式

来源:互联网 发布:oa系统的数据库设计 编辑:程序博客网 时间:2024/06/12 18:38

原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.
说白了就是一个类实现了Cloneable,重写clone方法,就可以调用这个类的对象复制实例了。

1、拷贝分类

原型模式中的拷贝分为"浅拷贝"和"深拷贝":浅拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量只复制引用,不复制引用的对象.深拷贝: 对值类型的成员变量进行值的复制,对引用类型的成员变量也进行引用对象的复制.

2、浅拷贝演示1

a.定义一个Prototype类
        public class Prototype implements Cloneable {            private String name;            public String getName() {                return name;            }            public void setName(String name) {                this.name = name;            }            public Object clone() {                try {                    return super.clone();                } catch (CloneNotSupportedException e) {                       e.printStackTrace();                    return null;                }            }         }
b.使用
        public class TestMain {            public static void main(String[] args) {                testPrototype();            }            private static void testPrototype(){                Prototype pro = new Prototype();                pro.setName("original object");                Prototype pro1 = (Prototype)pro.clone();                pro.setName("changed object");                System.out.println("original object:" + pro.getName());                System.out.println("cloned object:" + pro1.getName());            }        }        结果:        original object:changed object        cloned object:original object

3、浅拷贝演示2

我们定义一个Prototype类,不去实现Cloneable接口,看看这个类里面的属性能不能被复制(答案是不能的)a.我们定义一个Prototype类,不去实现Cloneable接口
        public class Prototype{            private String name;            public String getName() {                return name;            }            public void setName(String name) {                this.name = name;            }         }
b.定义一个NewPrototype,实现Cloneable接口
        public class NewPrototype implements Cloneable {            private String id;            public String getId() {                return id;            }            public void setId(String id) {                this.id = id;            }            //将上面的类作为这个类的一个属性,看看能不能clone            private Prototype prototype;            public Prototype getPrototype() {                return prototype;            }            public void setPrototype(Prototype prototype) {                this.prototype = prototype;            }            public Object clone(){                 try {                    return super.clone();                } catch (CloneNotSupportedException e) {                    e.printStackTrace();                    return null;                }              }        }
c.测试使用
        public class TestMain {            public static void main(String[] args) {                testPrototype();            }            private static void testPrototype(){                Prototype pro = new Prototype();                pro.setName("original object");                NewPrototype newObj = new NewPrototype();                newObj.setId("test1");                newObj.setPrototype(pro);                NewPrototype copyObj = (NewPrototype)newObj.clone();                copyObj.setId("testCopy");                //这个copyObj对象里面的属性prototype是没有复制的,指向的是同一个对象                copyObj.getPrototype().setName("changed object");                System.out.println("original object id:" + newObj.getId());                System.out.println("original object name:" + newObj.getPrototype().getName());                System.out.println("cloned object id:" + copyObj.getId());                System.out.println("cloned object name:" + copyObj.getPrototype().getName());            }        }        结果:        original object id:test1        original object name:changed object //已经改变了原来的值了        cloned object id:testCopy        cloned object name:changed object
可以看出来,不实现Cloneable的类属性是不能被复制的。如果要prototype这个属性也被复制,只要Prototype这个类实现Clonbeable接口就行。

4、深拷贝

利用串行化来做深复制把对象写道流里的过程是串行化(Serilization)过程;把对象从流中读出来是并行化(Deserialization)过程. 写在流里的是对象的一个拷贝,然后再从流里读出来重建对象.a.创建一个PrototypeSe类,实现Serializable序列化接口
        public class PrototypeSe implements Serializable {            private String name;            public String getName() {                return name;            }            public void setName(String name) {                this.name = name;            }        }
b.创建一个NewPrototypeSe,同样实现Serializable接口
        public class NewPrototypeSe implements Serializable {            private String id;            public String getId() {                return id;            }            public void setId(String id) {                this.id = id;            }            private PrototypeSe prototype;            public PrototypeSe getPrototype() {            return prototype;            }            public void setPrototype(PrototypeSe prototype) {                this.prototype = prototype;            }            public Object deepClone(){                try {                    ByteArrayOutputStream bo = new ByteArrayOutputStream();                    ObjectOutputStream oo = new ObjectOutputStream(bo);                       oo.writeObject(this);                       ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());                    ObjectInputStream oi = new ObjectInputStream(bi);                    return oi.readObject();                 } catch (IOException | ClassNotFoundException e) {                    e.printStackTrace();                    return null;                }            }        }   
c.使用
        public class TestDeepClone {            public static void main(String[] args) {                PrototypeSe po = new PrototypeSe();                po.setName("test1");                NewPrototypeSe se = new NewPrototypeSe();                se.setPrototype(po);                NewPrototypeSe deepClone = (NewPrototypeSe)se.deepClone();                deepClone.getPrototype().setName("test2");                System.out.println("original name:" + se.getPrototype().getName());                System.out.println("cloned name:" + deepClone.getPrototype().getName());            }        }        结果:        original name:test1        cloned name:test2
注意:原型类并没有实现Cloneable接口,而是自己定义一个deepClone方法复制
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 看重庆盘龙立交全貌 沙海吴邪计划的全貌 追尾全责自己要垫钱吗 对方全责不付钱找交警会管吗 一极全一极全责黄 对方全责不垫付怎么办 追尾全责扣几分 开车撞人全责扣几分 全责保险公司赔多少 追尾全责保险怎么赔 交通事故全责保险公司怎么赔 全责方不赔钱交警管吗 对方全责车险理赔流程 对方全责我不签字能放车吗 交强险自己全责怎么赔 车被追尾对方全责如何索赔 车子被撞对方全责怎样理赔 怎么通厕所蹲厕 深蹲膝盖疼怎么办 马桶蹲便器二合一 做深蹲能长高吗 九牧王蹲便器价格 蹲便器规格 全身照片 全身 全身美白针 美白全身 全身关节疼 全身关节痛 全身骨头疼 全身荨麻疹 美白针全身 全身肌肉痛 全身肌无力 全身起红点 瘦全身 如何瘦全身 突然全身痒 全身酸痛怎么回事 全身美白办法