学习笔记-设计模式之原型模式

本文内容源于视频教程,若有侵权,请联系作者删除。

一、概念

原型模式(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,大功告成!!!

posted @ 2020-07-19 01:48  落雨有清·风  阅读(131)  评论(0编辑  收藏  举报