Java设计模式之原型模式

154 阅读2分钟

原型模式用于创建重复的对象,同时又能保证性能。

当需要复制某个对象,并且该对象创建的代价比较大时,就可以使用原型模式,比如某数据从数据库中查询得到,可以将该对象进行缓存,下一次请求时返回该数据的克隆,减少对数据库的调用。

示例场景:

游戏中人物发射的子弹,每次发射都进行创建的话对性能会造成很大的影响,可以使用原型模式来拷贝子弹对象。

创建一个子弹类,实现Cloneable接口,使其可以被克隆:

package com.cc.prototype;
​
public class Bullet implements Cloneable {
    public Bullet() {
        try {
            // 模拟子弹创建耗时
            Thread.sleep(1000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
​
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

测试一下:

package com.cc.prototype2;
​
public class Main {
    public static void main(String[] args) throws CloneNotSupportedException {
        {
            // 没使用原型模式
//            for (int i = 0; i < 100; i++) {
//                Bullet bullet = new Bullet();
//                System.out.println(bullet);
//            }
        }
        {
            // 使用原型模式
            Bullet originBullet = new Bullet();
            for (int i = 0; i < 100; i++) {
            Bullet bullet = (Bullet) originBullet.clone();
                System.out.println(bullet);
            }
        }
    }
}

测试模块中,注释的部分是没有使用克隆,每一个bullet创建都需要1秒(模拟耗时),所以创建100个bullet需要100秒。使用了原型模式后,复制对象不走构造方法,它基于内存二进制流的复制,在性能上比直接new一个对象更加好。

原型模式的缺点:

  • 被克隆的类需要实现Cloneable接口
  • clone方法位于类内部,当对已有类进行改造时,需要修改代码,违反开闭原则
  • 当实现深克隆时,且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象都必须支持深克隆,实现起来比较麻烦