zoukankan      html  css  js  c++  java
  • 原型模式(设计模式_09)

    今天给大家介绍一种模式,原型模式

    例如:要创建很多个对象,常规思维是 new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),new 对象(),

    省略…


    原型模式可以去复制对象,而不是创建new对象,可以提高性能,以下就用一个案例来以说明:

    在用案例说明之前,首先了解 Cloneable接口

    Cloneable接口 (对象克隆):
    Object中的clone执行的时候使用了RTTI(run-time type identification)的机制,动态找到目前正在调用clone方法的那个reference,根据它的大小申请内存空间,然后进行bitwise的复制,将该对象的内存空间完全复制到新的空间中去,从而达到shallowcopy的目的,所以你调用super.clone() 得到的是当前调用类的副本,而不是父类的副本。


    // 定义一个原型类 实现 Cloneable接口
    public class Prototype implements Cloneable{
    
        // 返回 Prototype,这种方式 在 JDK1.8是不支持的
        /*
        protected Prototype clone() throws CloneNotSupportedException {
            Prototype prototype = (Prototype) super.clone();
            return prototype;
        }
        */
    
        /**
         * 实现Cloneable接口后,重写clone方法,此方法放回最终父类Object
         */
        protected Object clone() {
            Prototype prototype = null;
            try {
                prototype = (Prototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return prototype;
        }
    }
    
    // 原型Class继承 Prototype
    public class PrototypeClass extends Prototype{
    
        // 年龄
        private int age;
    
        // 传入年龄
        public void setAge(int age) {
            this.age = age;
        }
    
        /**
         * 此方法就是打印一句话
         */
        public void println() {
            System.out.println("PrototypeClass println()... 年龄是:" + age);
        }
    
    }
    
    // 客户端程序,传统方式,不使用原型模式
    public class Main {
    
        public static void main(String[] args) throws CloneNotSupportedException {
    
            // 不使用原型的方式
            PrototypeClass prototypeClass1 = new PrototypeClass();
            prototypeClass1.setAge(1);
            prototypeClass1.println();
    
            PrototypeClass prototypeClass2 = new PrototypeClass();
            prototypeClass2.setAge(2);
            prototypeClass2.println();
    
            PrototypeClass prototypeClass3 = new PrototypeClass();
            prototypeClass3.setAge(3);
            prototypeClass3.println();
    
            PrototypeClass prototypeClass4 = new PrototypeClass();
            prototypeClass4.setAge(4);
            prototypeClass4.println();
    
            PrototypeClass prototypeClass5 = new PrototypeClass();
            prototypeClass5.setAge(5);
            prototypeClass5.println();
    
            // 省略... 后续 写了一百次 new new PrototypeClass();
    
    }

    使用原型模式

    // 客户端程序,调用原型
    public class Main {
    
        public static void main(String[] args) throws CloneNotSupportedException {
    
    
            // 就是简单的 原型Class = new 原型Class,值new 这一次之后,后续不在重新去new,只拷贝对象:例如:
            PrototypeClass pc = new PrototypeClass();
    
            for (int i = 0; i < 100; i++) {
                // pc.clone(); 对象的复制
                PrototypeClass pcFor = (PrototypeClass) pc.clone();
                pc.setAge(i);
                pcFor.println();
            }   
        }
    }

    运行结果:
    这里写图片描述


    小故事
    这里写图片描述

    虢霭窿是热爱学习的学生,学习成绩很好,每一次考试自己的名字都几乎会写错,他爸爸知道这件事情之后,决定让他写自己的名字一百遍,于是就有了以下这些代码的实现:

    //定义一个原型类(我的名字) 实现 Cloneable接口
    public class MyName implements Cloneable{
    
        // 返回 MyName,这种方式 在 JDK1.8是不支持的
        /*
        protected MyName clone() throws CloneNotSupportedException {
            MyName myName = (MyName) super.clone();
            return myName;
        }
        */
    
        /**
         * 实现Cloneable接口后,重写clone方法,此方法放回最终父类Object
         */
        protected Object clone() {
            MyName myName = null;
            try {
                myName = (MyName) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return myName;
        }
    }
    
    // 写我的名字类 继承 原型
    public class WriteMyName extends MyName {
    
        // 写的内容
        private String context;
    
        // 封装写的内容
        public void setContext(String context) {
            this.context = context;
        }
    
        public void writeName() {
            System.out.println(context);
        }
    
    }

    常规的方式去抄写一百遍自己的名字:

    // 客户端程序
    public class Main {
    
        public static void main(String[] args) {
            WriteMyName myName1 = new WriteMyName();
            myName1.setContext("写虢霭窿第1遍");
            myName1.writeName();
    
            WriteMyName myName2 = new WriteMyName();
            myName2.setContext("写虢霭窿第2遍");
            myName2.writeName();
    
            WriteMyName myName3 = new WriteMyName();
            myName3.setContext("写虢霭窿第3遍");
            myName3.writeName();
    
            WriteMyName myName4 = new WriteMyName();
            myName4.setContext("写虢霭窿第4遍");
            myName4.writeName();
    
            WriteMyName myName5 = new WriteMyName();
            myName5.setContext("写虢霭窿第5遍");
            myName5.writeName();
    
            // 省略 ....
        }
    }

    最后虢霭窿写完了,发现好累啊


    原型模式去完成:

    // 客户端程序
    public class Main {
    
        public static void main(String[] args) {
            /**
            WriteMyName myName1 = new WriteMyName();
            myName1.setContext("写虢霭窿第1遍");
            myName1.writeName();
    
            WriteMyName myName2 = new WriteMyName();
            myName2.setContext("写虢霭窿第2遍");
            myName2.writeName();
    
            WriteMyName myName3 = new WriteMyName();
            myName3.setContext("写虢霭窿第3遍");
            myName3.writeName();
    
            WriteMyName myName4 = new WriteMyName();
            myName4.setContext("写虢霭窿第4遍");
            myName4.writeName();
    
            WriteMyName myName5 = new WriteMyName();
            myName5.setContext("写虢霭窿第5遍");
            myName5.writeName();
    
            // 省略 ....
            **/
    
            WriteMyName myName = new WriteMyName();
    
            for (int i = 0; i < 100; i++) {
                WriteMyName wmn = (WriteMyName) myName.clone(); 
                wmn.setContext("写虢霭窿第" + i + "遍");
                wmn.writeName();
            }
        }
    
    }

    运行结果:
    这里写图片描述

    以上是简单的原型模式示例,并不完善,谢谢大家观赏!!!


    谢谢大家的观看,更多精彩技术博客,会不断的更新,请大家访问,
    刘德利CSDN博客, http://blog.csdn.net/u011967006

  • 相关阅读:
    数学是最好的语言
    人类的语言--自然语言--》逻辑语言
    为什么大脑喜欢看图?
    思考是调用大脑存储的上下文对输入信息进行处理的过程
    Redis的相关问题总结
    TP5 关联模型使用(嵌套关联、动态排序以及隐藏字段)
    array_column 函数, 以及在PHP5.5之下的替代方法
    thinkphp在app接口开发过程中的通讯安全认证
    PHP开发APP接口实现--基本篇
    分布式与集群的区别是什么?
  • 原文地址:https://www.cnblogs.com/android-deli/p/10322220.html
Copyright © 2011-2022 走看看