【设计模式】原型模式(概念简介使⽤场景优缺点基本⽤法)
⽂章⽬录
I . 原型模式概念简介
原型模式 : ⽤原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象
① 设计模式类型 : 创建型设计模式 ;
② 原型实例对象 : 给出原型实例对象 , 根据该对象创建新对象 ;
③ 创建对象类型 : 创建对象的种类由原型的实例对象类型确定 ;
④ 创建⽅式 : 不调⽤构造函数 , ⽽是通过克隆原型的实例对象 , 使⽤现有对象创建另⼀个相同类型的对象 , 隐藏创建细节 ;
II . 原型模式使⽤场景
原型模式使⽤场景 : 原型模式的⽬的是 降低实例对象个数 , 减少构造函数的调⽤次数 ;
① 类初始化消耗资源过多 : 如果类初始化时消耗过多的资源 , 如这个类中某个成员占⽤⼤量内存 , 为了节省开销 ;
② 初始化繁琐耗时 : 类对象创建时经过⼤量的计算 , 或与本地资源 ( 数据库 , ⽂件 ) 频繁交互 , 每次创建消耗⼤量的 CPU 与 时间资源 ;
③ 构造函数复杂 : 类中定义的构造函数复杂 ;
④ 实例对象数量庞⼤ : 如果在内存中循环创建了很多该实例对象 , 就可以使⽤原型模式复⽤不⽤的对象 , ⽤于创建新对象 ;
III . 原型模式优缺点
1 . 原型模式优点 : 性能⾼ , 简单 ;
① 性能⾼ : 使⽤原型模式复⽤的⽅式创建实例对象 , ⽐使⽤构造函数重新创建对象性能要⾼ ; ( 针对类实例对象开销⼤的情况 )
② 流程简单 : 原型模式可以简化创建的过程 , 可以直接修改现有的对象实例的值 , 达到复⽤的⽬的 ; ( 针对构造函数繁琐的情况 )
2 . 原型模式缺点 : 实现复杂 , 坑多 ;
① 覆盖 clone ⽅法 ( 必须 ) : 必须重写对象的 clone ⽅法 , Java 中提供了 cloneable 标识该对象可以被拷贝 , 但是必须覆盖 Object 的clone ⽅法才能被拷贝 ;
② 深拷贝 与 浅拷贝 风险 : 克隆对象时进⾏的⼀些修改 , 容易出错 ; 需要灵活运⽤深拷贝与浅拷贝操作 ;
IV . 原型模式实现及简单⽰例
1 . 原型模式实现 :
① 对象创建原理 : 创建实例对象时使⽤原型模式 , 就是调⽤类的 clone ⽅法 , 直接克隆拷贝现有的实例对象 , ⽣成新的对象 ;
② 实现 Cloneable 接⼝ : 原型模式类需要实现 Cloneable 接⼝ , 如下⾯的 Student 类 ( class Student implements Cloneable ) 就实现了该接⼝ ;
③ 重写 clone() ⽅法 : 通常情况下直接调⽤⽗类的 clone ⽅法即可 , 这种⽅式是浅拷贝 ,
protected Object clone()throws CloneNotSupportedException{}
2 . 原型模式类代码⽰例 :
① 代码实现 : Student 类实现 Cloneable 接⼝ , 重写了 clone() ⽅法 , 直接调⽤⽗类的 clone() ⽅法 ;
② 地址打印 : 注意 toString 中调⽤到了⽗类的打印⽅法 , String() , 该⽅法打印 类名@地址 信息 , 可以帮助我们通过内存地址信息 , 看到是否真正的创建了⼀个新的实例对象 ;
/**
* 原型模式实现流程 : 使⽤ clone ⽅法实现原型模式
* 1 . 类继承 Cloneable 接⼝
* 2 . 实现 protected Object clone() ⽅法
*/
public class Student implements Cloneable {
private String name;
private int age;
public Student(){
System.out.println("调⽤ Student 默认构造函数");
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
@Override
protected Object clone()throws CloneNotSupportedException {
System.out.println("调⽤ Student clone ⽅法");
return super.clone();
}
@Override
public String toString(){
return"Student{"+
"name='"+ name +'\''+
", age="+ age +
", "+String()+
'}';
}
}
3 . 使⽤原型模式创建实例测试代码 :
java接口可以创建对象吗① 创建⼀个原型对象 : ⾸先使⽤构造函数 , 创建⼀个原型对象 newStudent , 之后的对象都是根据该原型对象 clone 创建的 ;
② 使⽤原型模式创建对象 : 循环中 , 通过调⽤原型对象 newStudent 的 clone() ⽅法 , 创建⼀个新的对象 ;
③ 性能分析 : 使⽤ clone ⽅法创建对象 , ⽐直接使⽤ new 构造函数⽅法开销更⼩ , 性能更⾼ , 如果要创建⼤量该对象⽰例 , 建议使⽤原型模式 , 使⽤ clone() ⽅法⼤量创建该对象 ;
public class Main {
public static void main(String[] args){
try{
//测试使⽤ clone ⽅法实现的原型模式 , 使⽤原型模式创建 10 个对象
Student newStudent =new Student();
/*
需求声明 : 此时要创建 10 个 Student 对象
依次调⽤⼀个创建好的 Student 对象的 clone ⽅法 10 次
即可创建 10 个不同的对象
适⽤场景 : 这是频繁创建⼤量的对象 , 该场景下适合使⽤原型模式
*/
for(int i =0; i <10; i++){
// 1 . 使⽤ clone ⽅法创建对象
Student student =(Student) newStudent.clone();
// 2 . 设置克隆出的对象参数
student.setName("Tom"+ i);
student.setAge(10+ i);
System.out.println(student);
}
}catch(CloneNotSupportedException e){
//捕获 clone ⽅法可能产⽣的异常
e.printStackTrace();
}
}
}
4 . 执⾏结果 : 通过打印出的字符串序列分析 , 注意每个对象的地址 Student@1b6d3586 , Student@4554617c … , 10 个对象的地址都不相同 , 说明每个对象都是⼀个新的实例对象 ;
调⽤ Student 默认构造函数
Student clone ⽅法
注册学⽣信息: Student{name='Tom0', age=10, kim.hsl.design.prototype.Student@1b6d3586}
Student clone ⽅法
注册学⽣信息: Student{name='Tom1', age=11, kim.hsl.design.prototype.Student@4554617c}
Student clone ⽅法
注册学⽣信息: Student{name='Tom2', age=12, kim.hsl.design.prototype.Student@74a14482}
Student clone ⽅法
注册学⽣信息: Student{name='Tom3', age=13, kim.hsl.design.prototype.Student@1540e19d}
Student clone ⽅法
注册学⽣信息: Student{name='Tom4', age=14, kim.hsl.design.prototype.Student@677327b6}
Student clone ⽅法
注册学⽣信息: Student{name='Tom5', age=15, kim.hsl.design.prototype.Student@14ae5a5}
Student clone ⽅法
注册学⽣信息: Student{name='Tom6', age=16, kim.hsl.design.prototype.Student@7f31245a}
Student clone ⽅法
注册学⽣信息: Student{name='Tom7', age=17, kim.hsl.design.prototype.Student@6d6f6e28}
Student clone ⽅法
注册学⽣信息: Student{name='Tom8', age=18, kim.hsl.design.prototype.Student@135fbaa4}
Student clone ⽅法
注册学⽣信息: Student{name='Tom9', age=19, kim.hsl.design.prototype.Student@45ee12a7}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论