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

例如:要创建很多个对象,常规思维是 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