befor
建议先看代码,可以更便于理解
什么是原型模式
原型模式用于需要重复创建的实例,当我们需要实例时通过封装好的方法获取数据相同但引用“地址”(与单例模式的不同之处)不同的实例
什么时候用
我们通常使用构造方法new关键字构建一个实例,原型模式是通过克隆clone的方法。new关键字速度是快于clone方法的,由此衍生出此问题什么时候用?我们不能为了使用设计模式而使用设计模式!
假设在我们使用构造方法的时候需要从数据库查询数据封装到实体中,每次创建都会进行查询数据库操作。在查询到的数据一定时间内不会改变的情况下这种行为是浪费性能的。
我们可以在初始化的时候查询数据库数据封装到实体中,每次创建新的对象时复制此对象并返回。
小结:当创建对象逻辑复杂且无意义的多次重复此逻辑,耗费性能远超clone时我们使用原型模式!
UML类图
代码实现
Persion类
package com.houyongchun.designpattern.prototypemode;
/**
* @author tjc
* @version 1.0
* @date 2021/3/20 0020 13:28
* @description 一个描述
*/
public class Persion implements Cloneable { private int age; public Persion() { /* 用此处写死的默认年龄 来表示重复且无意义的操作,在实际开发中默认年龄可能出现在数据库 , 配置文件里或直接放在页面中。不必过于关注此处 查询数据库等操作 this.age = db.query(); */ System.out.println("构造逻辑执行"); this.age = 18; } public int getAge() { return age; } @Override public Object clone() { Object clone=null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; } public Object clone2() { Object clone=null; try { clone = super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return clone; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
PersionFactory
package com.houyongchun.designpattern.prototypemode;
/**
* @author tjc
* @version 1.0
* @date 2021/3/20 0020 13:37
* @description 一个描述
*/
public class PersionFactory { //此处使用饿汉式单例模式 只执行一次构造方法 使用静态是为了保证构造只使用一次.如果使用多次那么和new一个对象没什么区别 private static Persion persion = new Persion(); public static Persion getPersion(){ /* 此处写的比较简单目的是去除无用杂质,像质点的概念一样。 帮助学习此模式的人理解 */ return (Persion) persion.clone(); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
TestClass
package com.houyongchun.designpattern.prototypemode;
/**
* @author tjc
* @version 1.0
* @date 2021/3/20 0020 13:35
* @description 一个描述
*/
public class TestClass { public static void main(String[] args) { thisTime(); } private static void thisTime(){ /* 平常使用的构造方法的方式创建实体类,多次执行内部逻辑浪费性能 */ Persion persion1 = new Persion(); Persion persion2 = new Persion(); Persion persion3 = new Persion(); } private static void prototypeMode(){ /* 使用原型模式创建: 调用模型模型创建方法获取实例的克隆对象 输出地址值如果地址值不一样说明是新克隆的对象 */ Persion persion4 = PersionFactory.getPersion(); Persion persion5 = PersionFactory.getPersion(); Persion persion6 = PersionFactory.getPersion(); System.out.println("地址值"+persion4); System.out.println("地址值"+persion5); System.out.println("地址值"+persion6); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
执行流程
1.使用new的方式获得三个实例
1.1TestClss main方法调用thisTime()
执行结果为走了三次构造方法逻辑
2.使用原型模式clone方法获取对象
构造逻辑只执行一次达到预期效果。
总结
使用原型模式方法获取实例有效避免重复的对象创建提高效率。**
如果您觉得文章写的还不错请您点个赞评论也可以,如果有什么疑惑请评论哦。
写在后面
可能会有人注意到Persion类除了重写Clone方法,还有一个Clone2方法,此处是为了说明使用克隆并不是一定需要重写Clone方法。
写在的后面
实现克隆:1.实现Cloneable接口 2.提供公共的方法在公共的方法内调用Object的java本地方法Clone();
再写点吧
1.实现Cloneable接口是规范约束,作为可克隆的类的一种标记 ,Cloneable接口内并没有任何方法
2.Object是所有类的父类,所以在当前想要克隆的类做super.clone();可以克隆当前类,因为Clone是Java本地方方法所以不用实现 ,本地方法相当于c++写的底层。
native是对本地方法的描述
写着写着感觉每个知识点都互相依赖,又无法对每一个点一一解释(太多了),不懂得地方参见其他教程。
文章来源: blog.csdn.net,作者:极致想象-对岸的蜗牛,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/TJC100_1001_10/article/details/115027787