zoukankan      html  css  js  c++  java
  • 3,原型模式

    一、什么是原型模式

    原型模式(Prototype)模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用 原型模式(Prototype)模式创建的实例,具有与原型一样的数据。

    二、原型模式的特点

    1,由原型对象自身创建目标对象。也就是说,对象创建这一动作发自原型对象本身。

    2,目标对象是原型对象的一个克隆。也就是说,通过Prototype模式创建的对象,不仅仅与原型对象具有相同的结构,还与原型对象具有相同的值。

    3,根据对象克隆深度层次的不同,有浅度克隆与深度克隆。

    三、例子

    创建一个原型类:

    一个原型类,只需要实现Cloneable接口,覆写clone方法,此处clone方法可以改成任意的名称,因为Cloneable接口是个空接口。

    public class Persion implements Cloneable{
        // 姓名
        private String name;
        // 年龄
        private int age;
        // 性别
        private String sex;
        //地址
        private List<String> addr;
        
        public List<String> getAddr() {
            return addr;
        }
        public void setAddr(List<String> addr) {
            this.addr = addr;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        //浅复制
        public Persion clone() {
            try {
                return (Persion) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return null;
            }
        }
    }

    创建一个测试类:

    public class TestClass {
        public static void main(String[] args) {
            Persion p1 = new Persion();
            List<String> list = new ArrayList<String>();
            list.add("测试地址");
            p1.setAge(11);
            p1.setName("张三");
            p1.setSex("男");
            p1.setAddr(list);
            
            System.out.println("P1:age:" + p1.getAge() + " name:" + p1.getName() + " sex:" + p1.getSex() + " addr:" + p1.getAddr().toString());
            //复制一个Persion对象
            Persion p2 = p1.clone();
            System.out.println("P2:age:" + p2.getAge() + " name:" + p2.getName() + " sex:" + p2.getSex() + " addr:" + p1.getAddr().toString());
            
            //修改后的P2
            p2.setAge(15);
            p2.setName("未完");
            p2.setSex("女");
            //向p1再次添加了一个地址,这会影响到p2的addr,可以看出浅复制对于引用类型复制的是引用类型的地址
            list.add("测试地址2");
            p1.setAddr(list);
            //修改p2并不会影响到p1,
            System.out.println("修改后的P1:age:" + p1.getAge() + " name:" + p1.getName() + " sex:" + p1.getSex() + " addr:" + p1.getAddr().toString());
            System.out.println("修改后的P2:age:" + p2.getAge() + " name:" + p2.getName() + " sex:" + p2.getSex() + " addr:" + p2.getAddr().toString());
        }
    }

    浅复制和深复制:

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

            深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。

    可以看出浅复制对于引用类型只是复制了内存地址,并不是把引用类型再复制一份。我们可以深复制可以吧把引用类型也复制一份。

    修改persion的clone方法如下:

    //深复制
    public Persion clone() {
        try {
            Persion p2 =  (Persion) super.clone();
            List<String> newAddrs = new ArrayList<String>();
            for (String string : addr) {
                newAddrs.add(string);
            }
            p2.setAddr(newAddrs);
            return p2;
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            return null;
        }
    }

    同样的测试代码再次运行:这次并没有影响到p2

    三、原型模式应用场景

    1,在创建对象的时候,我们不只是希望被创建的对象继承其基类的基本结构,还希望继承原型对象的数据。

    2,希望对目标对象的修改不影响既有的原型对象(深度克隆的时候可以完全互不影响)。

    3,隐藏克隆操作的细节。很多时候,对对象本身的克隆需要涉及到类本身的数据细节。

  • 相关阅读:
    帝国 标签模板 使用程序代码 去除html标记 并 截取字符串
    iis6 伪静态 iis配置方法 【图解】
    您来自的链接不存在 帝国CMS
    帝国cms Warning: Cannot modify header information headers already sent by...错误【解决方法】
    .fr域名注册 51元注册.fr域名
    帝国网站管理系统 恢复栏目目录 建立目录不成功!请检查目录权限 Godaddy Windows 主机
    星外虚拟主机管理平台 开通数据库 出现Microsoft OLE DB Provider for SQL Server 错误 '8004' 从字符串向 datetime 转换失败
    ASP.NET 自定义控件学习研究
    CSS层叠样式表之CSS解析机制的优先级
    ASP.NET程序员工作面试网络收藏夹
  • 原文地址:https://www.cnblogs.com/Zender/p/7201753.html
Copyright © 2011-2022 走看看