学习笔记-设计模式之原型模式
本文内容源于视频教程,若有侵权,请联系作者删除。
一、概念
原型模式(Prototype Pattern)是指原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
简言之:克隆
二、使用场景
1.需要创建大量相同类型的对象,比如打飞机游戏中的飞机
三、实现
需求:实现孙悟空的一个技能,拔一根猴毛,吹出千万个(1000个孙悟空)
1.常规写法
创建一个孙悟空,我们叫齐天大圣。
1 @AllArgsConstructor 2 public class QiTianDaSheng implements Cloneable{ 3 4 /** 身高 */ 5 public int heihgt; 6 /** 体重 */ 7 public int weight; 8 /** 生日 */ 9 public Date birthDay; 10 11 }
接下来创建1000个孙悟空。
1 public class PrototypeTest { 2 public static void main(String[] args) { 3 List<QiTianDaSheng> list = new ArrayList<>(); 4 QiTianDaSheng qiTianDaSheng; 5 for (int i = 0; i < 1000; i++) { 6 qiTianDaSheng = new QiTianDaSheng(185, 80, new Date()); 7 list.add(qiTianDaSheng); 8 } 9 } 10 }
很明显,这样存在很多问题。新建1000个对象,对内存消耗极大。
2 原型模式
1 @AllArgsConstructor 2 public class QiTianDaSheng implements Cloneable{ 3 4 /** 身高 */ 5 public int heihgt; 6 /** 体重 */ 7 public int weight; 8 /** 生日 */ 9 public Date birthDay; 10 11 @Override 12 protected QiTianDaSheng clone() throws CloneNotSupportedException { 13 return (QiTianDaSheng) super.clone(); 14 } 15 }
通过继承Cloneable类的clone方法会直接拷贝原始数据流,绕过了很多常规步骤(类加载,实例化,初始化等),速度比实例化快得多。
现在给孙悟空新增一个属性:金箍棒
1 @AllArgsConstructor 2 public class JinGuBang { 3 /** 高 */ 4 public int height; 5 /** 宽 */ 6 public int wide; 7 }
如今孙悟空变成
1 @Data 2 @AllArgsConstructor 3 public class QiTianDaSheng implements Cloneable{ 4 5 /** 身高 */ 6 public int heihgt; 7 /** 体重 */ 8 public int weight; 9 /** 生日 */ 10 public Date birthDay; 11 /** 金箍棒 */ 12 public JinGuBang jinGuBang; 13 14 @Override 15 protected QiTianDaSheng clone() throws CloneNotSupportedException { 16 return (QiTianDaSheng) super.clone(); 17 } 18 }
再看看下面测试类
1 public class PrototypeTest { 2 public static void main(String[] args) throws CloneNotSupportedException { 3 List<QiTianDaSheng> list = new ArrayList<>(); 4 JinGuBang jinGuBang = new JinGuBang(1000, 500); 5 QiTianDaSheng qiTianDaSheng = new QiTianDaSheng(188, 80, new Date(), jinGuBang); 6 QiTianDaSheng qiTianDaSheng1 = qiTianDaSheng.clone(); 7 QiTianDaSheng qiTianDaSheng2 = qiTianDaSheng.clone(); 8 System.out.println(qiTianDaSheng1.getJinGuBang() == qiTianDaSheng2.getJinGuBang()); 9 } 10 }
输出结果为true。那完了,所有孙悟空用的同一根金箍棒,这样会打起来。
这里涉及到了一个知识点:深克隆和浅克隆。浅克隆只能拷贝原始数据类型,对于对象的拷贝只是拷贝其地址,这就是为什么孙悟空那么多,金箍棒却只有一个的原因,而深克隆则是将对象中的原始类型和对象一起拷贝。
1 @Data 2 @AllArgsConstructor 3 public class QiTianDaSheng implements Cloneable{ 4 5 /** 身高 */ 6 public int heihgt; 7 /** 体重 */ 8 public int weight; 9 /** 生日 */ 10 public Date birthDay; 11 /** 金箍棒 */ 12 public JinGuBang jinGuBang; 13 14 @Override 15 protected QiTianDaSheng clone() throws CloneNotSupportedException { 16 QiTianDaSheng qiTianDaSheng = (QiTianDaSheng) super.clone(); 17 qiTianDaSheng.setJinGuBang(this.jinGuBang.clone()); 18 return qiTianDaSheng; 19 } 20 }
接着执行上面测试类,结果为false,大功告成!!!